volatile关键字
volatile关键字本身的意思是它所修饰的变量是不稳定的,在运行过程中有可能会被改变成新的值。主要运用在系统编程中处理多线程问题。
编译器优化
介绍volatile关键字之前,先了解以下编译器在做什么工作,对于多个变量,当第一次出现的时候,编译器会把变量的值从内存中取出来放到更快的缓存中去,然后利用寄存器参与运算。当我们再次去取变量的值的时候,就不需要到内存中去取了,而是直接去寄存器中拿出来就行了。
编译器优化可能导致的两个问题:
1、当当前变量因为别的线程原因值发生改变(缓存中),寄存器中的值不会发生改变,导致读取到的值与实际的变量的值是不一致的
2、但是如果寄存器里的值发生改变,原变量的值实际上是不发生改变的(缓存中),也会导致读到的值跟实际值是不一致的。
例如,假设有a,b,c三个变量
int a = 10;
int b = a;
int c = a;
第一次把10赋值给a的时候,就会把变量a赋值为10,然后第二步b也会老老实实的到内存中去取关于a值,但是到了第三步的时候,由于第二步的原因,会导致编译器懒得去内存中去取,直接在缓存中拿到a的值,这样就减少了再读一次的效率。但是对于下面情况
volatile int a = 10;
int b = a;
int c = a;
在第三步的时候,变量c会老老实实的去内存中取a的值,这样的a的值才是最准确的。由于volatile意思是告诉编译器我这个变量在运行过程中是可能发生改变的,就不要编译器优化了,每次取值的时候必须都给我到内存中去取去。确保程序不会报错。
volatile与const比较
const
指的是程序不能对变量进行修改,或者说尝试去修改,但是他的作用域仅限于当前程序环境下,如果全局变量需要用到const
前面需要加一个extern
关键字。如果程序中有指针指向了const
所修改的变量地址,在实际只想的是const
变量的一个拷贝的地址。
Q1:一个参数既可以是const
也可以是volatile
的吗
答:是可以的,对于只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。const 是指A程序不能对a 变量的值进行修改,但是B程序可能会对a的值修改,恰好A程序有在检测a这个变量,那这时候就需要这两个关键字同时去修饰变量。同时修饰表示:表示一个变量在程序编译期不能被修改且不能被优化;在程序运行期,变量值可修改,但每次用到该变量的值都要从内存中读取,以防止意外错误。
注意:指针也可以是volatile
的