我在2001年发现了一篇关于Dobbs博士的文章:volatile - Multithreaded Programmer's Best Friend。我总是发现'volatile'有点无用 - 至少作为变量的限定符 - 因为对线程之间共享的变量的访问总是会经历某种类型的库层。
尽管如此,将类实例和方法标记为“易变”以表明文章中提到的线程安全程度似乎非常引人注目。
为了快速总结一下这篇文章,核心思想是宣布一个这样的类:
struct SomeObject {
void SingleThreadedMethod();
void Method();
void Method() volatile;
};
然后,类的实例,如下:
// An object that will only be accessed from a single thread.
SomeObject singleThreaded;
// An objecect that will be accessed from multiple threads.
volatile SomeObject sharedObject;
sharedObject.SingleThreadedMethod(); //this will be an compile error
sharedObject.Method(); // will call the volatile overload of Method
singleThreaded.Method(); // would call the non volatile overload of Method.
我们的想法是实现像“Method()volatile”这样的方法:
void SomeObject::Method() volatile {
enter_critical_section();
const_cast<Method*>(this)->Method();
leave_critical_Section();
}
显然,智能指针可以自动化原子锁定和转换为非易失性的进程 - 关键是volatile的限定符可以在其预期用途中用于标记类成员和实例以指示它们如何'将从多个线程中使用,因此让编译器告诉开发人员何时在volatile对象上调用单线程(非易失性)方法,或者甚至自动选择线程安全版本。
我对这种方法的质疑是:'volatile'合格方法的性能影响是什么?是否强制编译器假定在volatile函数中访问的所有变量都需要被视为volatile,从而被排除在优化机会之外?局部变量会被排除在优化之外吗?如果是这样,对于任何不稳定的合格成员函数来说,这可能是一个巨大的性能拖累。
答案 0 :(得分:11)
this
不会是一个易失性指针,因此访问它不会每次都从内存中加载它。但是this
将是指向volatile的指针,这意味着*this
被视为易失性