好的,阿杰 😊 我来详细讲一下 C 语言中 volatile
的用法,并配合实例说明。
一、volatile
的作用
volatile
是 C 语言中的一个 类型修饰符,它的主要作用是告诉 编译器不要对这个变量进行优化,每次使用该变量时都要 直接从内存中读取真实值,而不是使用寄存器中的缓存值。
换句话说:
👉 volatile
变量可能会被 外部环境修改,编译器不能假设它不会改变。
二、适用场景
- 硬件寄存器
#define UART_STATUS (*(volatile unsigned int *)0x40001000)
外设寄存器的值可能随时变化,必须声明为volatile
。 - 多线程/多任务共享变量
volatile int flag = 0; void thread1() { while (flag == 0) { // 等待另一个线程修改 flag } } void thread2() { flag = 1; // 线程2修改,线程1能立即感知 }
- 中断服务程序(ISR)中修改的变量
volatile int interrupt_occurred = 0; void ISR_Handler() { interrupt_occurred = 1; } int main() { while (!interrupt_occurred) { // 等待中断触发 } printf("中断触发了!\n"); }
三、和 const
的组合
const volatile
:值可能改变,但程序不能直接修改它const volatile int timer_reg = *(int *)0x40001000;
四、容易踩的坑
- 只保证可见性,不保证原子性
volatile
并不能保证多线程操作的安全性,比如自增操作x++
依然不是原子的。- 需要配合 互斥锁 或 原子操作 来保证线程安全。
- 和优化相关
- 没有
volatile
时,编译器可能把变量缓存到寄存器,导致值更新不及时。
- 没有
五、总结口诀
- 读硬件 → volatile
- 跨线程共享 → volatile
- 中断变量 → volatile
- 不要指望它保证原子性!
发表回复