原文:https://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html
1. 为什么用volatile?
C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明:
volatile关键字是一种类型修饰符,用它声明的变量可以被某些编译器未知的因素修改,例如操作系统、硬件或者其他线程。遇到用这样修饰的关键字声明的变量,编译器不在对访问该变量的代码进行优化,从而可以提供对特殊地址的稳定访问。A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided.
声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如:
1 | volatile int i=10; |
2 | int a = i; |
3 | ... |
4 | // 其他代码,并未明确告诉编译器,对 i 进行过操作 |
5 | int b = i; |
2.volatile 指针
和 const 修饰词类似,const 有常量指针和指针常量的说法,volatile 也有相应的概念:
修饰由指针指向的对象、数据是 const 或 volatile 的:
1
const
char
* cpch;
2
volatile
char
* vpch;
注意:对于 VC,这个特性实现在 VC 8 之后才是安全的。
指针自身的值——一个代表地址的整数变量,是 const 或 volatile 的:
1
char
*
const
pchc;
2
char
*
volatile
pchv;
注意:(1) 可以把一个非volatile int赋给volatile int,但是不能把非volatile对象赋给一个volatile对象。
(2) 除了基本类型外,对用户定义类型也可以用volatile类型进行修饰。
(3) C++中一个有volatile标识符的类只能访问它接口的子集,一个由类的实现者控制的子集。用户只能用const_cast来获得对类型接口的完全访问。此外,volatile向const一样会从类传递到它的成员。3. 多线程下的volatile
有些变量是用volatile关键字声明的。当两个线程都要用到某一个变量且该变量的值可以改变得时候,应该用volatile声明,该关键字的作用是防止优化编译器把变量装入CPU的寄存器中。如果变量被装入CPU寄存器,那么两个线程可能一个使用内存中的变量,一个使用寄存器中的变量,这样会造成程序错误。volatile的意思是让编译器每次操作都从内存中真正取出,而不是使用寄存器中的值。