volatile关键字解析!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zhang_1218/article/details/86489596

volatile关键字解析!

在C、C++、JAVA等语言中,使用volatile关键字声明的变量或者对象通常具有优化、多线程相关的特殊属性。通常,volatile作为类型修饰符,其在不同的语言中的用法和语义有所不同。
在C语言中,其作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
准确地说就是编译器在用到volatile变量时,提醒编译器,volatile变量随时可能改变,因此编译后的程序每次需要存储或者读取这个变量的时候,都要直接从变量地址中读取,而不是使用保存在寄存器里的备份。
如果,没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,则会产生不一致的现象。

C和C++中,volatile关键字的作用:
1、允许访问内存映射设备
2、允许在setjmp和longjmp之间使用变量
3、允许在信号处理函数中使用sig_atomic_t变量
————引用维基百科

由于volatile的作用,故而其应用场景如下:
1、并行设备的硬件寄存器
存储器映射的硬件寄存器通常也要加上volatile,因为编译器每次对它的读写都有可能有不同的含义,故而要保证每次要都要精确读取。
例如只读的状态寄存器,它是volatile的,因为它可能会被意外的修改。但要注意的是,它同时也是const的,因为它是只读的,程序不应该试图去修改它。

2、一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。

3、多线程应用中被几个任务共享的变量
当多线程都要用到某一个变量或对象时,其值可能会随时多次变化,故应该用volatile声明,此时其作用是防止编译器优化,把变量从内核装入寄存器中。如果变量被装入CPU的寄存器中的话,那么多线程可以有的线程会使用内存中的变量,有的使用寄存器中的变量,获取的值不同,则会造成错误。

volatile在日常应用的情况如上所述,平常也会遇到相关的问题。
如:一个参数能否既有const修饰,又有volatile修饰?答案当然是肯定的,如前面所述,只读的状态寄存器就同时被const、volatile修饰,以保证其可见性和准确性。
一个指针可以是volatile吗?可以的,当一个中断服务子程序修改一个指向buffer的指针时。

结语:volatile 作为类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,保证了内存的可见性。但是同时也要注意,频繁地使用volatile很可能会增加代码尺寸和降低性能,因此要合理的使用volatile。

猜你喜欢

转载自blog.csdn.net/Zhang_1218/article/details/86489596