c++ - 在这里删除 c++ volatile 是否安全?

标签 c++ c++11 volatile

在这里从 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/

相关文章:

c++ - 为什么重新声明 std::cout 会导致段错误?

c++ - 调整QListView的高度以适应内容

C++如何找出数组中最连续的数字?

c++ - 在不提供定义的情况下覆盖函数有什么意义?

c++ - 当我0-初始化一个vector时,它和calloc有同样的效果吗?

c++ - 为什么 const_cast away volatile 只适用于指针

Java volatile 内存排序及其在 x86-64 上的编译

c++ - 如何在此输出中每四个字符之间放置一个空格?

c++ - 奇怪的初始化优化

c++ - icpc错误隐式生成的赋值运算符无法复制引用成员(提升图)