我了解使用C语言中的volatile
关键字在内存映射硬件寄存器、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++;
}
我可以理解为什么在情况1下,如果没有
volatile
,编译器可能会错误地优化while
,因为变量的更改来自硬件,编译器可能无法看到从代码中进行的任何变量更改。但是对于情况2和3,为什么需要使用volatile呢?在这两种情况下,变量被声明为全局,编译器可以看到它在多个位置中被使用。所以,如果变量不是
volatile
,为什么编译器会优化while
循环呢?是因为编译器设计上不知道“异步调用”(在ISR的情况下)还是多线程吗?但这不可能,对吧?
此外,情况3看起来像是一个常见的多线程程序,没有
volatile
关键字。假设我给全局变量添加了一些锁定(没有volatile
关键字):int var = 0;
int task1()
{
lock(); // some mutex
while (var == 0) { do sth }
release()
}
int task2()
{
lock();
var++;
release();
}
在我看来,它看起来很正常。那么在多线程编程中,我真的需要使用volatile
吗?为什么我以前从未见过在多线程程序中添加volatile
限定符以避免优化的变量呢?
task1
存在未定义的行为。 - Kerrek SB