1、volatile关键字的作用
volatile关键字修饰的变量是“易变的”,表示这个变量可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字修饰的变量时,编译器不能对访问该变量的代码进行优化,每次读取该变量的时候都只能从内存中读取,不能直接读取寄存器中的值。volatile int value :当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。
volatile int i=10;
int a = i;
...
// 其他代码,并未明确告诉编译器,对 i 进行过操作
int b = i;
其中volatile指出每次读取变量i都需要从内存中读取,若没有volatile的话,因为中间的代码没有对i进行过操作,那么编译器会对代码进行优化,将上次读取到的值直接赋值给b,而不是到内存中读取。
int square(volatile int* pti){
return *pti * *pti;
}
上面函数用来计算平方值,但是由于pti指针指向的是一个volatile修饰的变量,所以编译器编译后得到的函数类似于下面函数的效果,a和b的值可能不相同,所以函数得到的结果可能不是期望的平方值。
int square(volatile int* pti){
int a = *pti;
int b = *pti;
return a * b;
}
2、多线程与volatile
volatile不能用于多线程的同步,多线程中volatile类型的变量仍然需要加锁或者使用atomic。volatile并不是用来解决多线程竞争问题的,而是用来表示这个变量可以被某些编译器未知的因素更改,以提醒编译器不要对该变量的访问擅自进行优化。volatile并不能保证操作的原子性,在读取、写入变量的过程中仍然可能被其他线程打断导致意外结果发生。