我读到了 Cvolatile
关键字在内存映射硬件寄存器、ISR 和多线程程序中的用法。
1) 注册
uint8_t volatile * pReg;
while (*pReg == 0) { // do sth } // pReg point to status register
2) ISR
int volatile flag = 0;
int main()
{
while(!flag) { // do sth }
}
interrupt void rx_isr(void)
{
//change flag
}
3) 多线程
int volatile var = 0;
int task1()
{
while (var == 0) { // do sth }
}
int task2()
{
var++;
}
我可以看到为什么编译器会错误地优化while
情况 1)如果volatile
不存在,因为变量更改是由硬件进行的,编译器可能看不到代码对变量的任何更改。
但是对于案例 2) 和 3),为什么需要 volatile 呢?在这两种情况下,变量都被声明为global,编译器可以看到它在多个地方使用。while
那么,如果变量不是,为什么编译器会优化循环volatile
呢?
是因为编译器的设计不知道“异步调用”(在 ISR 的情况下)还是多线程?但这不可能,对吧?
此外,case 3) 看起来像一个没有volatile
关键字的多线程中的普通程序。假设我为全局变量添加了一些锁定(无volatile
关键字):
int var = 0;
int task1()
{
lock(); // some mutex
while (var == 0) { do sth }
release()
}
int task2()
{
lock();
var++;
release();
}
对我来说这看起来很正常。那么我真的需要volatile
多线程吗?为什么我以前从未见过volatile
将限定符添加到变量以避免多线程程序中的优化?