Max*_*kin 6 c++ volatile c++11
volatile
从m_flag
这里的定义中删除是否安全?如果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();
}
Run Code Online (Sandbox Code Playgroud)
T.C*_*.C. 10
通常,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;
因此,线程发生在之后的读取之前,因此发生在后续读取之前.([intro.multithread]/p13-14)
由于有上没有其他副作用m_flag
,m_flag = true;
是可见的副作用相对于该读出([intro.multithread]/P15),因此该读必须读什么存储在由可见的副作用,即,true
.
无论是否volatile
使用,"优化"该条件的编译器都是不符合的.