在这里从 m_flag
的定义中删除 volatile
是否安全?
如果 m_flag
不是易变的,什么会阻止编译器优化这个循环的条件:while (!m_flag) m_cv.wait(lock);
?
标准(C++11 之后)是否明确规定在这种情况下禁止进行此类优化?
#include <mutex>
#include <condition_variable>
#include <future>
#include <iostream>
using namespace std;
class foofoo
{
volatile bool m_flag;
mutex m_mutex;
condition_variable m_cv;
public:
void DoWork()
{
m_flag = false;
unique_lock<mutex> lock(m_mutex);
auto junk = async(std::launch::async, [this]()
{
{
unique_lock<mutex> lock(m_mutex);
m_flag = true;
}
m_cv.notify_one();
});
while (!m_flag) m_cv.wait(lock);
cout << "ququ" << endl;
}
};
int main()
{
foofoo f;
f.DoWork();
}
最佳答案
一般来说,volatile
和多线程在 C++11 中是正交的。使用 volatile
既不会增加也不会消除数据竞争。
在这种情况下,m_flag = true;
排序在由 async
([intro. execution]/p14),它又同步随后在m_cv.wait(lock)
([thread.mutex.requirements.mutex]/p11 ,25),这又是 在 m_flag
的后续读取之前排序的。 m_flag = true;
因此,线程间发生在之前,因此发生在,随后的读取。 ([介绍.多线程]/p13-14)
由于 m_flag
没有其他副作用,m_flag = true;
是关于读取的可见副作用([ intro.multithread]/p15),因此读取必须读取可见副作用存储的内容,即 true
。
无论是否使用 volatile
,“优化”掉该条件的编译器都是不符合规范的。
关于c++ - 在这里删除 c++ volatile 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29665259/