等待 std::thread 完成
Posted
技术标签:
【中文标题】等待 std::thread 完成【英文标题】:Waiting for a std::thread to finish 【发布时间】:2013-11-13 18:53:25 【问题描述】:我正在尝试在程序终止时优雅地清理,所以我在 std::thread
上调用 join()
以等待它完成。这似乎永远阻塞了主线程,但我不明白为什么,因为工作线程是一个(几乎)空循环,如下所示:
void GameLoop::Run()
while (run)
// Do stuff...
std::cout << "Ending thread...\n";
当然,我在 join
ing 之前将 run
设置为 false。现在,我怀疑这与它是一个成员函数并在对象destruction 上被调用有关。我正在创建这样的线程:runThread.reset(new thread(&GameLoop::Run, this));
,其中runThread
是unique_ptr<std::thread>
和GameLoop
的成员。 join()
调用来自 GameLoop
对象的析构函数。
如果它的对象正在被销毁,循环线程可能无法完成?根据调试器的说法,循环线程在msvcr120d.dll
的黑暗深处徘徊。如果有,你会怎么处理?
注意:这里是std::thread
的新手!
更新:这是我加入析构函数的呼吁:
run = false;
if (runThread->joinable())
runThread->join();
更新 2:如果我删除 join()
,我会收到 ~thread()
引发的异常!
【问题讨论】:
我希望你在某处将 run 设置为 false/0... 将其定义为 volatile 是个好主意。 你能贴出你的析构函数的相关代码吗? @AlexFarber - 将其定义为std::atomic
是一个更好的主意。 volatile
没有可移植语义,对线程间同步没有用处。
如果你删除了 join(),你会得到一个异常,因为线程对象在线程完成之前不能被破坏(除非已经调用了 detach)。
我对你描述的代码的作用没有任何问题...coliru.stacked-crooked.com/a/7555dac44353ca50
【参考方案1】:
当然,当你join
一个线程不会导致线程终止。它只是阻塞,直到该线程因自然(或非自然)原因而死亡。
为了优雅地清理多线程应用程序,您需要以某种方式告诉工作线程它是时候死亡了,然后等待死亡发生。 “等待死亡发生”部分是 join
的用途。
【讨论】:
我将 run 设置为 false。让我更新一下问题。【参考方案2】:啊,显然运行时库中存在错误。根据this question,在静态对象的析构函数中线程未成功结束。我的GameLoop
是一个包含在静态GameSystem
中的非静态对象。我会检查这是否属实并更新。
是的,已确认。在第一次使用时遇到错误只是我的运气!
【讨论】:
那么您还需要确保run
在多线程环境中正常运行。
好的,谢谢,我已将其更改为原子以上是关于等待 std::thread 完成的主要内容,如果未能解决你的问题,请参考以下文章