【发布时间】:2016-01-20 11:00:54
【问题描述】:
假设有一个由主线程控制的布尔标志 (keep_running)。另一个线程无限循环,直到该标志变为假。
int main() {
bool keep_running(true);
std::thread run( [](bool &keep_running)
{
while(keep_running)
{
// do work
}
}, std::ref(keep_running) );
// do other work
keep_running = false;
run.join();
return 0;
}
该标志应该是原子的吗?
std::atomic<bool> keep_running
我想,非原子版本可能发生的最糟糕的情况是标志在发生时设置正确
while(keep_running)
被执行。在这种情况下,循环会继续运行一次(并非严格需要)迭代。但就我而言,这是可以接受的。
是否存在上述代码可能出错的情况?
编辑:
出于性能原因(并且没有错误),我对此最感兴趣。因此,在循环中使用 std::atomic 作为标志会对性能产生负面影响吗?
【问题讨论】:
-
在旧版本的 C++ 中,您会使用
volatile- 没有它,从一个线程对变量的写入可能不会从另一个线程看到。但是,由于在 C++11 中有atomic,您应该使用它来防止同样的问题。 -
当然应该是原子的。这为您提供了正确的语义。你为什么想做其他事情?
-
我在想,我既不需要围绕标志的内存屏障,也不需要关心指令重新排序。因此,我认为我可以摆脱 std::atomic 以获得性能。我试图通过编辑问题来澄清这一点。但我没有意识到变量可能会卡在寄存器中,正如 Tsyvarev 在下面的回答中指出的那样。
标签: c++ multithreading c++11 atomic