我读到了 volatile 关键字,但我不知道在什么情况下应该使用它。
当内存(变量)被更新并且进程没有意识到这一点时?
在什么情况下驱动程序应该使用 volatile 变量?
我读到了 volatile 关键字,但我不知道在什么情况下应该使用它。
当内存(变量)被更新并且进程没有意识到这一点时?
在什么情况下驱动程序应该使用 volatile 变量?
在我的世界中,最常见的情况是当您对使用内存映射 I/O 的微控制器进行编程时。寄存器中的值可能会因外部数字输入而改变,但如果您不将变量声明为volatile
,编译器可能会完全优化代码,您会想知道为什么没有任何效果。
Matt 建议我对关于代码“优化”的声明进行修饰。内存映射 I/O 在代码中通过指针访问。当您想要检查按钮的状态时,通常会将寄存器的值与按钮的位掩码按位与。如果你不指定 volatile,编译器会说,“嘿,你的代码实际上从来没有改变那个指针的值,所以我将删除你按位与它的那个语句,因为值总是相同!”。
希望这能澄清我的陈述。谢谢你的建议,马特。
正如您已用linux-device-driver
标签标记的那样,在 Linux 内核中进行编码的一些具体建议可能是有序的。
通常,您不需要编写volatile
Linux 内核代码。在volatile
可能需要的情况下,它的使用包含在您应该调用的核心内核函数中。例如,如果您正在执行内存映射 I/O,那么您应该使用ioremap()
,writel()
等readl()
。
除了其他人所说的,volatile关键字通常是为了防止编译器形式进行优化。在寄存器值不断变化的某些存储器映射寄存器(例如,RTC 时钟寄存器)中,使用了易失性关键字。看看这个例子:
RTC_CLOCK _time;
TIME _currentTime = _time ;
while(_currentTime - _time >= 100)
{
//Do something
}
//rest of the code
如果我们不在 TIME 之前附加 volatile 关键字,则此代码将像 _currentTime - _time = 0 一样,编译器不会考虑它下面的 while 循环:
RTC_CLOCK _time;
TIME _currentTime = _time ;
//rest of the code
为了防止这种情况,我们必须在 TIME 中使用 volatile 关键字。
易失性变量是可以在任何时候更改的变量,程序不知道它。
我想不出 volatile 关键字在日常编程中有什么用处,但它可能会出现。
据我所知,在 C 中,volatile
当对来自多个源(进程)的变量执行并发非同步操作时,应使用该关键字。如果声明了变量volatile
,那么所有进程将始终直接从其内存位置访问该变量,而不是将变量复制到微处理器的缓存中并从那里访问它。
请注意,这将显着降低该特定变量的性能。内存中变量的访问时间约为毫秒,而对于 1 级或 2 级缓存变量,访问时间约为十分之一纳秒,因此仅在考虑所有其他选项时才使用它们。