从具有本地 std::thread 对象的函数中退出而没有加入

Posted

技术标签:

【中文标题】从具有本地 std::thread 对象的函数中退出而没有加入【英文标题】:Exiting from a function that has a local std::thread object without join 【发布时间】:2017-10-30 12:55:55 【问题描述】:

我有以下简单的功能,只是为了演示:

void thread_func(int i) 
    return i;

我还有另一个函数在新线程中调用它并且不等待它返回:

void my_nice_function() 
    std::thread t(thread_func, 15);

由于tmy_nice_function()中的一个局部变量,我担心当my_nice_function()退出时,t会在运行时被销毁。

有理由担心吗? 即使从my_nice_function()返回后,如何让线程t在后台运行?

【问题讨论】:

你必须在t被销毁之前调用join()detach(),否则~thread析构函数调用terminate()并因此中止程序。 When should I use std::thread::detach?的可能重复 我不认为这是重复的,因为不是每个人都知道std::detach 是什么。使用std::detach 似乎是这里的答案 @SomethingSomething,该链接解释了 detach 的作用。有这个问题的人可以通过链接回答他们的问题。 我的问题的答案不是 detach() 所做的答案,而是我应该使用 detach() - 一个我以前不知道的功能,可能其他开发人员也不知道'吨。我同意指向那里作为答案并告诉“使用分离()并阅读该帖子”很好,但这不是重复的问题 【参考方案1】:

您的担忧是有道理的。阅读合适的reference documentation for std::thread 告诉我们关于销毁:

如果*this 有关联的线程(joinable() == true),则调用std::terminate()

所以在不分离或加入的情况下销毁t 将结束您的程序。

因此,您有两种选择,具体取决于您想要发生的事情。如果您希望函数等待线程完成,请在返回之前调用t.join()。如果您希望线程在函数返回后继续运行,请调用t.detach()

【讨论】:

所以我的情况的解决方案是在创建t之后添加t.detach(),对吧? (鉴于我不想等待线程完成,但我确实希望它在后台运行)【参考方案2】:

是的,这是一个令人担忧的原因。该代码将无法按预期工作。你可以这样做

t.join ()

如果你想让你的主函数等到线程函数的执行,就应该这样写。完成了。 或者

t.detach ()

如果你想要线程函数,应该调用它。独立运行,我的意思是主要功能。不应该等待它完成。

您也可以使用睡眠 (x)。如果您希望函数仅运行 x 秒。 通常不建议调用 terminate(),因为它会杀死所有线程,包括 main() 线程。没有必要杀死一个线程。当线程中运行的函数完成时,线程会自动清理自己。

参考这个:How to Destroy a thread object

【讨论】:

以上是关于从具有本地 std::thread 对象的函数中退出而没有加入的主要内容,如果未能解决你的问题,请参考以下文章

C++ 多线程std::thread 详解

C++ 多线程std::thread 详解

具有与 std::thread 不同的线程库的 C++ thread_local

如何使用一个 std::thread 对象来运行 2 个顺序事件(函数)?

std::thread 从一个函数开始而不等待线程完成[重复]

c++11的std::thread能用类的成员函数构造一个线程吗?语法怎样?