C ++ 11:如果不为std :: thread调用join()会发生什么 [英] C++11: What happens if you don't call join() for std::thread

查看:785
本文介绍了C ++ 11:如果不为std :: thread调用join()会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面给出:

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 will exit after 5 seconds, what will happen to th1 that's still executing?

即使您在main中定义的th1线程对象超出范围并被销毁,它是否仍继续执行直到完成?

Does it continue executing until completion even if the th1 thread object you defined in main goes out of scope and gets destroyed?

th1是在执行完毕后还是坐在那里还是在程序终止时以某种方式清理掉?

Does th1 simply sits there after it's finished executing or somehow gets cleaned up when the program terminates?

如果线程是在函数中创建的,而不是在main中创建的,该线程会一直存在直到程序终止或函数超出范围时该怎么办?

What if the thread was created in a function, not main - does the thread stays around until the program terminates or when the function goes out of scope?

如果您想要某种类型的超时行为,简单地不为线程调用join是否安全?

Is it safe to simply not call join for a thread if you want some type of timeout behavior on the thread?

推荐答案

如果在调用析构函数时尚未分离或加入线程,则它将调用std::terminate,我们可以通过转到草稿C ++ 11标准我们看到,该部分30.3.1.3 线程析构函数说:

If you have not detached or joined a thread when the destructor is called it will call std::terminate, we can see this by going to the draft C++11 standard we see that section 30.3.1.3 thread destructor says:

如果为joinable(),则调用std :: terminate().否则,没有任何效果. [ 注意:隐式分离或加入其中的joinable()线程 它的析构函数可能会导致难以调试正确性(对于 分离)或性能(用于连接)错误,仅当 引发异常.因此,程序员必须确保 当线程仍可连接时,永远不会执行析构函数. -结尾 注意]

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 ]

关于此行为的基本原理,我们可以在(不)使用std :: thread

as for a rationale for this behavior we can find a good summary in (Not) using std::thread

为什么可连接线程的析构函数必须调用 std :: terminate?毕竟,破坏者可以与孩子一起 线程,或者它可能与子线程分离,或者可能取消 线程.简而言之,您无法加入析构函数,因为这样做会 导致意外(未在代码中明确指出)程序 如果f2抛出则冻结.

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.

,然后是一个示例,并说:

and an example follows and also says:

您无法分离,因为这可能会冒主线程的风险 离开子线程在其中启动的作用域,并且该子线程 线程继续运行并保留对已经存在的作用域的引用 不见了.

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:重新考虑线程对象的销毁分离,这与先前的建议相抵触,该建议是在可以连接时在销毁时分离的,并且它指出,两个替代方案之一将是联接,这可能导致死锁,另一个替代方案是今天,如果可以连接,则销毁状态为std::terminate.

The article references N2802: A plea to reconsider detach-on-destruction for thread objects which is argument against the previous proposal which was detach on destruction if joinable and it notes that one of the two alternatives would be to join which could lead to deadlocks the other alternative is what we have today which is std::terminate on destruction if joinable.

这篇关于C ++ 11:如果不为std :: thread调用join()会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆