【发布时间】:2012-12-31 04:42:22
【问题描述】:
我想检查 std::thread 是否已完成执行。搜索 stackoverflow 我发现以下question 解决了这个问题。接受的答案建议让工作线程在退出之前设置一个变量并让主线程检查这个变量。以下是此类解决方案的一个最小工作示例:
#include <unistd.h>
#include <thread>
void work( bool* signal_finished ) {
sleep( 5 );
*signal_finished = true;
}
int main()
{
bool thread_finished = false;
std::thread worker(work, &thread_finished);
while ( !thread_finished ) {
// do some own work until the thread has finished ...
}
worker.join();
}
评论接受的答案的人声称不能使用简单的bool 变量作为信号,代码在没有内存屏障的情况下被破坏,使用std::atomic<bool> 是正确的。我最初的猜测是这是错误的,一个简单的bool 就足够了,但我想确保我没有遗漏任何东西。 上述代码是否需要std::atomic<bool> 才能正确?
让我们假设主线程和工作线程在不同套接字的不同 CPU 上运行。我认为会发生的是,主线程从其 CPU 的缓存中读取thread_finished。当工作线程更新它时,缓存一致性协议负责将工作线程更改写入全局内存并使主线程的 CPU 缓存无效,因此它必须从全局内存中读取更新后的值。使上述代码正常工作的缓存一致性难道不是重点吗?
【问题讨论】:
-
为什么不使用条件变量或信号量或 autoresetevent 来向线程发出信号?这就是这些东西的用途。
-
如果编译器根据您一遍又一遍地测试变量的值并最终修改应用程序的行为这一事实进行了一些优化,则可能会出现问题。我从未见过这种情况发生,但我听说这可能是使用原子而不是简单布尔值的原因。
-
@TonyTheLion:条件变量、信号量和事件用于您想要等待(暂停线程)直到发生某些事情。他只是想测试是否发生了某些事情,因此原子布尔更合适。
-
另请参阅此答案的 cmets:stackoverflow.com/a/12087141/819272
标签: c++ c++11 stdthread stdatomic