我需要为另一个线程设置一个标志来退出.另一个线程会不时检查退出标志.我是否必须使用原子作为旗帜或只是一个普通的布尔就足够了(为什么(如果我使用普通布尔可能会出错的例子)?
#include <future>
bool exit = false;
void thread_fn()
{
while(!exit)
{
//do stuff
if(exit) break;
//do stuff
}
}
int main()
{
auto f = std::async(std::launch::async, thread_fn);
//do stuff
exit = true;
f.get();
}
Run Code Online (Sandbox Code Playgroud)
And*_*owl 29
我是否必须使用atomic来"退出"bool变量?
是的.
atomic<bool>通过(例如)使用或使用手动同步std::mutex.您的程序当前包含数据争用,其中一个线程可能正在读取变量而另一个线程正在编写它.这是未定义的行为.
根据C++ 11标准的第1.10/21段:
程序的执行包含数据竞争,如果它在不同的线程中包含两个冲突的动作,其中至少有一个不是原子的,并且都不会在另一个之前发生.任何此类数据争用都会导致 未定义的行为.
" 冲突 " 的定义见第1.10/4段:
如果其中一个修改内存位置(1.7)而另一个访问或修改相同的内存位置,则两个表达式评估会发生冲突.
Pet*_*ker 12
是的,你必须有一些同步.正如你所说,最简单的方法是atomic<bool>.
正如@AndyProwl所说的那样,语言定义说在这里不使用原子会给出未定义的行为.这有很好的理由.
首先,可以通过线程切换中途中断对变量的读取或写入; 另一个线程可能会看到部分写入的值,或者如果它修改了值,原始线程将看到一个混合值.其次,当两个线程在不同的核心上运行时,它们具有单独的缓存; 写入值会将其存储在缓存中,但不会更新其他缓存,因此线程可能看不到其他线程写入的值.第三,编译器可以根据它看到的内容重新组织代码; 在示例代码中,如果循环内部没有任何内容更改值exit,编译器没有任何理由怀疑该值会发生变化; 它可以将循环转换为while(1).
原子学解决了所有这三个问题.
| 归档时间: |
|
| 查看次数: |
6434 次 |
| 最近记录: |