我阅读了关于volatile关键字,但我不知道在什么情况下我应该使用它。哪里可以使用volatile?
当内存(变量)得到更新,进程没有意识到这一点?
驱动程序在什么情况下会使用volatile变量?
我阅读了关于volatile关键字,但我不知道在什么情况下我应该使用它。哪里可以使用volatile?
当内存(变量)得到更新,进程没有意识到这一点?
驱动程序在什么情况下会使用volatile变量?
在我的世界中最常见的情况是当你编程使用内存映射I/O的微控制器时。由于外部数字输入,寄存器中的值可能会发生变化,但如果您没有声明变量为volatile
,则编译器可能会完全优化代码,您会想知道为什么没有任何效果。
Matt建议我修改关于代码获得“优化”的声明。内存映射I/O通过指针访问代码。当你想检查一个按钮的状态时,你通常会将该寄存器的值与按钮的位掩码进行按位与运算。如果你没有指定volatile,编译器会说:“嘿,你的代码永远不会改变这个指针的值,所以我会在你把它与位进行与运算的时候删除那个语句,因为这个值总是一样!”。
希望这可以清楚我的发言。感谢您的建议,马特。
你应该进入“优化它”的意思,而我们中的一些人熟悉这意味着什么,它可能不适用于所有人。 – 2010-09-06 06:29:32
正如您所标记这个与linux-device-driver
标签这可能会对你有所帮助
,Linux内核中的编码一些具体的建议可能是为了。
一般情况下,您不需要在您的Linux内核代码中编写volatile
。在可能需要volatile
的情况下,它的使用被封装在您应该调用的核心内核函数中。例如,如果你正在做内存映射I/O,那么你就应该使用ioremap()
,writel()
等
从我所知,在C应使用readl()
的volatile
关键字,其中并发非同步操作执行上来自多个来源(过程)的变量。如果变量声明为volatile
,则所有进程将始终直接从其存储器位置访问该变量,而不是将该变量复制到微处理器的高速缓存中并从那里访问该变量。
请注意,这将显着降低该特定变量的性能。内存中变量的访问时间以毫秒为单位,而对于第1级或第2级缓存变量,它大约在十分之几纳秒左右,因此只有在考虑了所有其他选项时才使用它们。
是否可以对来自多个源(进程)的变量进行并发的非同步操作? – Pointer 2010-09-06 08:13:39
@Yogesh:是的。最简单的例子是一个从信号处理程序写入并在程序主循环中读取的变量(例如,“清理并终止asap”标志)。其他包括各种形式的共享内存,如共享内存映射文件。 – 2010-09-06 12:26:39
除了其他人所说的,volatile关键字通常是为了防止编译器形式进行优化。 在某些内存映射寄存器中,寄存器的值保持在chinagin上,如使用rtc时钟值的volatile关键字。 看看这个例子:
RTC_CLOCK _time;
TIME _currentTime = _time ;
while(_currentTime - _time >= 100)
{
//Do something
}
//rest of the code
如果我们不把这段代码时间之前会是这样的_currentTime volatile关键字 - _time = 0,编译器不会考虑它下面的while循环:
RTC_CLOCK _time;
TIME _currentTime = _time ;
//rest of the code
为了防止发生这种情况,我们必须在TIME中使用volatile关键字。
优秀的混凝土,易于理解的答案。并没有充满关于它如何帮助并发的虚假废话。 – 2013-09-13 03:07:17
请参阅:http://stackoverflow.com/questions/2535148/volatile-qualifier-and-compiler-reorderings(虽然另一个问题有C++和C标签都记住C++从C获得了这个关键字)。 – dirkgently 2010-09-06 06:18:32
From Dr Dobbs - http://www.drdobbs.com/184403766;jsessionid=4HI2GRADWCN51QE1GHRSKHWATMY32JVN – pankajt 2010-09-06 06:23:11
参见[ 为什么在c中需要volatile? ](http://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c)。 – 2010-09-06 06:23:33