为什么通过std :: atomic使用volatile限定符?

时间:2010-03-19 16:53:00

标签: c++ c++11 atomic volatile

从我从Herb Sutterothers读到的内容,您会认为volatile和并发编程是完全正交的概念,至少就C / C ++而言。< / p>

但是,在GCC中implementation所有std::atomic的成员函数都具有volatile限定符。安东尼·威廉姆斯的std::atomic atomic<>也是如此。

那么有什么问题,我的volatile变量是否需要{{1}}?

3 个答案:

答案 0 :(得分:77)

总结别人的正确写法:

C / C ++ volatile用于硬件访问和中断。 C ++ 11 atomic<>用于线程间通信(例如,在无锁代码中)。这两个概念/用途是正交的,但是它们具有重叠的要求,这就是为什么人们经常混淆两者。

atomic<>具有volatile限定函数的原因与具有const限定函数的原因相同,因为原则上对象既可以是atomic<>也可以是const和/或volatile

当然,正如我的文章所指出的,另一个混淆的原因是C / C ++ volatile与C#/ Java volatile不同(后者基本上等同于C + +11 atomic<>)。

答案 1 :(得分:56)

为什么volatile中使用std::atomic限定符?

因此易失性对象也可以是原子的。见here

相关引用是

  

定义函数和操作以使用volatile对象,因此应该是volatile的变量也可以是原子的。但是,volatile的限定符不是原子性所必需的。

我的atomic<>变量是否需要volatile

不,原子对象不必是易变的。

答案 2 :(得分:15)

作为const,volatile是传递性的。如果将方法声明为volatile,则无法对其或其任何成员属性调用任何非易失性方法。通过std::atomic方法volatile,您允许在包含volatile变量的类中使用std::atomic成员方法进行调用。

我没有一个美好的一天...这么令人困惑......也许一个小例子有帮助:

struct element {
   void op1() volatile;
   void op2();
};
struct container {
   void foo() volatile {
      e.op1();  // correct
      //e.op2();  // compile time error
   }
   element e;
};