给出如下:
void test()
{
std::chrono::seconds dura( 20 );
std::this_thread::sleep_for( dura );
}
int main()
{
std::thread th1(test);
std::chrono::seconds dura( 5 );
std::this_thread::sleep_for( dura );
return 0;
}
main
将在 5 秒后退出,仍在执行的 th1
会怎样?
即使您在 main
中定义的 th1
线程对象超出范围并被销毁,它是否会继续执行直到完成?
th1
是在完成执行后简单地坐在那里,还是在程序终止时以某种方式被清除?
如果线程是在函数中创建的,而不是 main
- 线程是否会一直存在直到程序终止或函数超出范围?
如果您希望线程上有某种类型的超时行为,那么不为线程调用 join
是否安全?
最佳答案
如果在调用析构函数时您没有分离或加入线程,它将调用 std::terminate
,我们可以通过转到 draft C++11 standard 看到这一点我们看到 30.3.1.3
thread destructor 部分说:
If joinable(), calls std::terminate(). Otherwise, has no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note ]
至于这种行为的基本原理,我们可以在 (Not) using std::thread 中找到很好的总结。
Why does the destructor of a joinable thread have to call std::terminate? After all, the destructor could join with the child thread, or it could detach from the child thread, or it could cancel the thread. In short, you cannot join in the destructor as this would result in unexpected (not indicated explicitly in the code) program freeze in case f2 throws.
下面还有一个例子,还说:
You cannot detach as it would risk the situation where main thread leaves the scope which the child thread was launched in, and the child thread keeps running and keeps references to the scope that is already gone.
文章引用N2802: A plea to reconsider detach-on-destruction for thread objects这是反对先前提案的论据,该提案在可连接时在销毁时分离,它指出两种选择之一是连接,这可能导致死锁,另一种选择是我们今天拥有的 std::terminate
如果可连接则销毁。
关于C++11:如果不为 std::thread 调用 join() 会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40112119/