本文记录了C语言中 Volatile 关键字的作用。
变量使用 volatile 修饰
- 告诉编译器,该变量随时会发生变化,每次使用该变量直接到内存中去读取,而不是使用暂存在寄存器中的值
- 因为当程序中多次读取同一个变量中的值时,编译器会将该变量进行优化,将该变量暂存到寄存器或缓存中供程序使用,而这时如果我们访问该变量的值时,程序就会取寄存器或暂存里的值,而不是内存中的值。这个缓存中的值和内存中的值不一致
- 当使用 volatile 修饰时,会告诉编译器,不能把该变量优化存储到缓存里面,当程序访问该变量时,都会去内存中读取该变量,这样取出的值才是实际的值。
- 遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法:int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。
- 会阻止编译器对可变对象的优化,而这些优化是编译器无法预知的
- volatile 修饰,系统总是会从主存里读取值,而不是从临时缓存里读取
volatile 使用场景
其实不只是内嵌汇编操纵栈"这种方式属于编译无法识别的变量改变,另外更多的可能是多线程并发访问共享变量时,一个线程改变了变量的值,怎样让改变后的值对其它线程 visible。一般说来,volatile用在如下的几个地方:
- 中断服务程序中修改的供其它程序检测的变量需要加 volatile;
- 多任务环境下各任务间共享的标志应该加 volatile;
- 存储器映射的硬件寄存器通常也要加 volatile 说明,因为每次对它的读写都可能由不同意义;
多线程下的volatile
当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值。
参考:
https://www.runoob.com/w3cnote/c-volatile-keyword.html
https://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html