前言
- volatile是什么,为什么被发明?
- volatile为什么用?
- volatile什么时候使用?
- const和volatile能同时使用,为什么?
volatitle是什么?
volatile 的字面意思为“不稳定的,易变的”。它是被设计用来修饰被不同线程访问和修改的变量,每次读取变量都从变量的内存地址中访问,防止变量更新不同步。
volatile为什么用?
讲一个小例子:
int Flag;
interrupt ISR_Uart1(void) { if() Flag = 0; else Flag = 1; } main() { if(Flag == 0) do something; elsedo others; }
全局变量Flag,可能随时被中断改变,如果不用volatile修饰,当调整编译器优化级别时,可能此Flag会被优化,导致使用的时候,使用寄存器内的值,而不是内存地址中的值,造成了Flag值的变化不同步。所以Debug时正常,优化烧写后就不正常了。所以使用全局变量的时候,尽量使用volatile进行修饰。
例如wiki百科中
volatile什么时候使用?
1、中断中改变的值
2、多任务中,相互之间共享的值
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义
const和volatile能同时使用,为什么?
const表示本程序代码层面上不能改变此变量,如果不小心手误改变,编译时应报错。
volatile表示本程序外可能会改变此变量,编译器不能优化掉。
例如:
const volatile int i = 0; main() { if(1 == i) do something; }
如果此程序中,没有代码给i赋值为1,则编译器以可能会把if直接优化掉,但是这个i可能被其他地方修改(例如状态寄存器)。
总结:
由于有中断、流水线执行模式(变量先从RAM读取到寄存器),多线程,这些资源共享的情况下,导致变量的改变和使用是并发的,而不是串行的(时间有先后,可一目了然的把控),所以变量存在着竞争。
volatile的作用,最终目的是为了让程序员能够准确的把控程序的执行,不会因为竞争,导致变量被意外改变,产生Bug。
记得一句话,如果你都不知道自己的程序是如何执行的,就别先忙着调试。
延伸知识:
1、什么是内存和寄存器?有什么关系?
2、什么是原子操作?
参考资料:
1、百度百科