由于我对这个问题的回答,我开始阅读关键字volatile以及关于它的共识.我看到有很多关于它的信息,一些旧的现在看起来是错的,而且很多新的说它在多线程编程中几乎没有位置.因此,我想澄清具体的用法(在SO上找不到确切的答案).
我还想指出我一般都理解编写多线程代码的要求,以及为什么volatile不解决问题.不过,我看到代码volatile用于我工作的代码库中的代码.此外,这是我使用volatile关键字的唯一情况,因为所有其他共享资源都已正确同步.
假设我们有一个类:
class SomeWorker
{
public:
SomeWorker() : isRunning_(false) {}
void start() { isRunning_ = true; /* spawns thread and calls run */ }
void stop() { isRunning_ = false; }
private:
void run()
{
while (isRunning_)
{
// do something
}
}
volatile bool isRunning_;
};
Run Code Online (Sandbox Code Playgroud)
为简单起见,有些事情被遗漏了,但重要的是创建了一个对象,它在新生成的线程中执行某些操作,检查a(volatile)布尔值以了解它是否应该停止.只要希望工作者停止,就会从另一个线程设置此布尔值.
我的理解是,volatile在这种特定情况下使用的原因只是为了避免任何将其缓存在循环寄存器中的优化.因此,导致无限循环.没有必要正确地同步事物,因为工作线程最终将获得新值?
我想知道这是否被认为是完全错误的,如果正确的方法是使用同步变量?编译器/架构/核心之间有区别吗?也许这只是一个值得避免的草率方法?
如果有人澄清这一点,我会很高兴.谢谢!
编辑
我有兴趣看到(在代码中)你如何选择解决这个问题.
我只是在阅读Anthony Williams的行动书中的C++并发性.有这个经典的例子有两个线程,一个产生数据,另一个消耗数据,AW写的代码很清楚:
std::vector<int> data;
std::atomic<bool> data_ready(false);
void reader_thread()
{
while(!data_ready.load())
{
std::this_thread::sleep(std::milliseconds(1));
}
std::cout << "The answer=" << data[0] << "\n";
}
void writer_thread()
{
data.push_back(42);
data_ready = true;
}
Run Code Online (Sandbox Code Playgroud)
我真的不明白为什么这个代码与我使用经典的挥发性bool而不是原子的不同.如果有人能够对这个问题敞开心扉,我将不胜感激.谢谢.