我们有一个表示原子整数的包装器。在内部,它是使用Windows InterlockedIncrement()
和InterlockedDecrement()
函数实现的,这些函数适用于volatile long
变量:
class AtomicInt {
public:
...
operator long() const { return m_value; }
private:
volatile long m_value;
};
我的问题是,上面的运算符是否正确查询当前值(即你总是得到当前值)或者我是否需要将该方法声明为volatile
以防止缓存值出现任何问题? / p>
答案 0 :(得分:2)
你所做的很好......你不需要将方法标记为易失性。此外,由于您已在类声明中包含方法的定义,因此该方法通常由编译器隐式内联,因此在编译器优化过程中将省略实际的函数调用机制。因此,在大多数情况下,变量本身将直接访问而无需中间函数调用,从而使变量上的volatile
声明足够。
volatile
关键字不足以确保使用共享内存值的线程不接收缓存数据。通常,volatile
关键字仅阻止某些编译器优化。在具有较弱内存一致性规则的处理器平台(即ARM,PowerPC等)上,即使变量标记为volatile,您仍然可以最终从本地处理器核心访问缓存值。解决这个问题的方法是实现适当的内存屏障,以确保刷新和刷新实际处理器内存缓存中的任何过时值。这些当然是依赖于平台的指令......在您的情况下,好消息是您正在使用的编译器内在函数将确保您的AtomicInt
类不会遇到这些问题,但我确实想要您了解围绕volatile
关键字的这一一般性问题。
答案 1 :(得分:0)
足以让m_value
变得不稳定。这足以阻止优化访问方法。