c++ 易失性和多线程:以下线程安全?

假设有两个线程分别运行Thread1()和Thread2()。线程1只设置一个全局标志来告诉线程2退出,线程2定期检查是否应该退出。

volatile bool is_terminate = false;

void Thread1()
{
    is_terminate = true;
}

void Thread2()
{
    while (!is_terminate) {
        // ...
    }
}

假设对is_terminate的访问是原子的,我想询问上述代码是否安全。我已经知道许多材料状态,挥发性不能一般地保证螺纹安全。但是在共享一个原子变量的情况下,我们真的需要使用锁来保护共享变量吗?

这可能是线程安全的。

线程安全往往取决于上下文。更新bool总是线程安全的,如果你从来没有读过它。
如果你从中读出来的话,这个答案取决于你读取的时间,读取的是什么意思。

在某些CPU上,但不是全部,对bool类型的对象的写入将是原子的。 x86 CPU通常会使其成为原子,但其他可能不会。如果更新不是原子,那么添加volatile将不会帮助你。

但下一个问题是重新排序。编译器(和CPU)将按照指定的顺序执行对volatile变量的读/写操作,而无需重新排序。这样很好

但是,它不能保证对所有非易失性存储器访问的一个易失性存储器访问重新排序。因此,一个常见的例子是您定义某种标志来保护对资源的访问,使标志变为易失性,然后编译器将资源访问权移动,以便在检查标志之前发生。允许这样做,因为它不是重新排序两个易失性访问的内部排序,而只是一个易失性和非易失性访问。

老实说,我问的问题是为什么不做正确呢?
在这种情况下,波动是有可能发挥作用的,但是为什么不把自己拯救出来,而且更清楚它是否正确?在其周围拍摄记忆障碍。

翻译自:https://stackoverflow.com/questions/6592287/volatile-and-multithreading-is-the-following-thread-safe

转载注明原文:c++ 易失性和多线程:以下线程安全?