[编辑]对于背景阅读,并且要清楚,这就是我所说的:volatile关键字简介
在查看嵌入式系统代码时,我看到的最常见错误之一是线程/中断共享数据的 volatile 遗漏。volatile
但是我的问题是,当通过访问函数或成员函数访问变量时不使用它是否“安全” ?
一个简单的例子;在下面的代码中......
volatile bool flag = false ;
void ThreadA()
{
...
while (!flag)
{
// Wait
}
...
}
interrupt void InterruptB()
{
flag = true ;
}
...变量flag
必须是 volatile 以确保 ThreadA 中的读取不会被优化,但是如果标志是通过函数读取的...
volatile bool flag = false ;
bool ReadFlag() { return flag }
void ThreadA()
{
...
while ( !ReadFlag() )
{
// Wait
}
...
}
......flag
仍然需要不稳定吗?我意识到它是 volatile 并没有什么坏处,但我关心的是何时省略它并且没有发现遗漏;这会安全吗?
上面的例子很简单;在实际情况中(以及我询问的原因),我有一个包装 RTOS 的类库,因此有一个抽象类 cTask 派生任务对象。这种“活动”对象通常具有访问数据的成员函数,这些函数可以在对象的任务上下文中修改但从其他上下文访问;那么,这些数据被宣布为易失性至关重要吗?
我真的对这些数据的保证内容感兴趣,而不是实际的编译器可能会做什么。我可能测试了许多编译器,发现它们永远不会优化通过访问器的读取,但有一天会发现一个编译器或编译器设置使这个假设不成立。例如,我可以想象,如果函数是内联的,那么这种优化对于编译器来说将是微不足道的,因为它与直接读取没有什么不同。