C++11:如果不为 std::thread 调用 join() 会发生什么

标签 c++ multithreading c++11 stdthread

给出如下:

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/

相关文章:

c++ - 隐藏物理 body 边界

c++ - sqlite,获得一行的最快方法是什么?

c++ - 图实现 : variable has initializer but incomplete type

c++ - OpenMP:从上到下的文本

c++ - 将 Eigen3 变换的旋转转换为 AngleAxis

java - 实现共享计算的 Future 接口(interface)

java - 电梯寻找楼层模拟中的逻辑存在缺陷

c++11 - cuda cpu 函数 - gpu 内核重叠

c++ - 使用 const char * 创建对象时使用 std::make_unique 时出现链接错误

c++ - 为什么 `basic_ios::swap` 只做部分交换?