这个问题是在阅读了其他开发人员编写的一些代码后出现的,所以我做了一些研究,发现了 Andrei Alexandrescu 的文章。在他的文章中,他说可以使用 volatile 布尔变量来忙等待(参见第一个示例等待/唤醒)
class Gadget
{
public:
void Wait()
{
while (!flag_)
{
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup()
{
flag_ = true;
}
...
private:
bool flag_;
};
我真的不明白它是如何工作的。
- volatile 不保证操作是原子的。实际上,对布尔变量的读/写是原子的,但理论并不能保证这一点。从我的角度来看,上面的代码可以使用 C++11 安全地重写,方法是使用 std::atomic::load/store 函数和相应的获取/释放内存排序约束。
- 在所描述的示例中我们没有这个问题,但是如果我们有不止一个写入,我们可能会遇到内存排序问题。Volatile 不是栅栏,它不强制内存排序,它只是阻止编译器优化。
那么为什么这么多人使用 volatile bool 来忙等待,它真的便携吗?