volatile关键字
在C和C++中,volatile
关键字用于告诉编译器某些特定的变量可能会在无意中被修改,从而防止编译器优化掉相关代码。当我们使用声明为volatile
类型的变量时,表示变量的值是随时可能发生变化的,并且需要特别小心地处理。
主要有以下几种情况需要使用volatile
关键字:
-
位域
当使用volatile
关键字定义位域时,保证相应的存储单元不被优化器优化,并且在访问每个位域时都会从该内存位置重新读取数据。由于位域只能定义为整型或枚举类型,因此如果一个结构体里面有位域成员,需要将整个结构体定义为volatile
类型才能保证可靠性。 -
中断服务程序中修改的变量
在一些嵌入式系统中,硬件设备产生中断信号后,中断服务程序需要马上执行,这时需要使用volatile
关键字来声明中断服务程序修改的变量,以免编译器优化掉相关代码。 -
多线程环境中被多个线程共享的变量
当多个线程访问同一个变量时,各线程之间对共享变量进行的操作可能不遵循程序的代码顺序,如果没有使用volatile
关键字,编译器可能会进行代码重排,导致程序运行结果与预期不符。
综上所述,volatile
关键字的作用是告诉编译器某个变量是易变的,需要特殊处理,以便正确地反映该变量在程序中的实际状态,避免因优化掉相关代码而引发的不可预期的问题。
举个例子:
下面是一个在嵌入式系统中的使用volatile
关键字的例子:
#include <stdio.h> // 定义一个计时器 volatile unsigned int timer = 0; // 模拟硬件中断服务程序,每隔一秒钟定时器值加1 void interrupt_service_routine() { while (1) { // 将定时器值加1 timer++; // 模拟延时 for (int i = 0; i < 0xFFFFF; i++); } } // 主函数,定时查询定时器的值 int main() { // 启动中断服务程序 interrupt_service_routine(); // 定时查询定时器的值并输出 while (1) { printf("Timer = %u\n", timer); // 模拟延时 for (int i = 0; i < 0xFFFFF; i++); } return 0; }
在上面的代码中,我们定义了一个volatile
类型的变量timer
,表示这个变量可能会被不同线程或中断服务程序所修改。然后,我们在一个死循环中不停地查询这个变量的值并输出,在主循环中也增加了一个模拟延时的操作。
而在interrupt_service_routine()
函数中,则通过一个死循环不停地将timer
变量的值加1,模拟每隔1秒钟就会产生中断并对该变量进行修改的情况。
因为timer
是一个易变的变量,可能被interrupt_service_routine()
函数随时修改,因此我们需要在声明该变量时使用volatile
关键字来告诉编译器进行特殊处理,并保证查询到的值是实际的最新值,避免了不可预期的运行结果。
本文作者:榴红八色鸫
本文链接:https://www.cnblogs.com/hezexian/p/17302604.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步