为啥我们使用 volatile 关键字? [复制]
Posted
技术标签:
【中文标题】为啥我们使用 volatile 关键字? [复制]【英文标题】:Why do we use volatile keyword? [duplicate]为什么我们使用 volatile 关键字? [复制] 【发布时间】:2011-05-25 03:56:36 【问题描述】:可能重复:Why does volatile exist?
我从未使用过它,但我想知道人们为什么使用它?它究竟是做什么的?我搜索了论坛,发现只有 C# 或 Java 主题。
【问题讨论】:
与 [C++: volatile 关键字何时对您有帮助? ](***.com/questions/72552/…)。 虽然这是重复的,但我认为 Nawaz 的回答比重复的问题更全面、更易于理解。 ***.com/a/65641563/13782669 【参考方案1】:在计算机编程中,尤其是在 C、C++ 和 C# 编程语言中,使用 volatile
关键字声明的变量或对象通常具有与优化和/或线程相关的特殊属性。一般来说,volatile
关键字旨在防止(伪)编译器对假定变量值不能“自行”更改的代码进行任何优化。 (c) ***
http://en.wikipedia.org/wiki/Volatile_variable
【讨论】:
volatile与线程无关 volatile 关键字是一个类型限定符,用于声明对象可以在程序中被操作系统、硬件或并发执行的线程等对象修改。 (c) MSDN C++ 参考。 (msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx) 但是msdn和wikipedia肯定是错的,你是对的。volatile
对线程没有帮助。易失性读/写仍然可以相对于非易失性重新排序,这使得它对于线程目的毫无用处。此外,您可能已经注意到 MSDN 页面上的“Microsoft Specific”大字。 Microsoft 的 volatile 实现提供了超出标准规定的额外保证。所以是的,从技术上讲,MSDN 是错误的。***可能出错也就不足为奇了。
虽然volatile
的属性与线程有关,但这是真的。在线程之间共享的变量上使用volatile
可以改变程序的语义。 volatile
只是不够强大,无法将语义更改为任何有用或明确定义的内容。
恐怕你不知道你在说什么@jalf。在一个线程中更改为变量的 volatile 关键字被授予者在所有线程中保持一致。通过根据该平台的需要插入栅栏、屏障、缓存刷新、重新加载等。如果你做过除了电脑开发以外的任何事情,你可能知道这一点。仅仅因为英特尔对您隐藏了很多缓存管理并不意味着它没有发生。【参考方案2】:
考虑这段代码,
int some_int = 100;
while(some_int == 100)
//your code
当这个程序被编译时,编译器可能会优化这个代码,如果它发现程序从不尝试改变some_int
的值,所以它可能会被优化while
循环通过将其从 while(some_int == 100)
更改为 something 相当于 while(true)
以便执行速度更快(因为 while
循环中的条件似乎是 true
总是)。 (如果编译器不优化它,那么它必须获取some_int
的值并将其与100 进行比较,在每次迭代中这显然有点慢。)
但是,有时,(程序的某些部分的)优化可能不希望,因为可能是其他人从程序外部更改some_int
的值编译器不知道,因为它看不到它;但这就是你设计它的方式。在这种情况下,编译器的优化将不会产生所需的结果!
因此,为确保获得所需的结果,您需要以某种方式阻止编译器优化while
循环。这就是volatile
关键字发挥作用的地方。你需要做的就是这个,
volatile int some_int = 100; //note the 'volatile' qualifier now!
换句话说,我会这样解释:
volatile
告诉编译器,
“嘿编译器,我是易变的,你 知道,我可以被一些 XYZ 改变 你甚至不知道。那 XYZ 可以是任何东西。也许有些 这个星球外的外星人叫 程序。也许一些闪电,一些 中断、火山等形式可以 变异我。可能是。你永远不知道是谁 会改变我!所以哦你 无知,别玩无所不知 上帝,不敢碰代码 我在哪里。好吗?”
嗯,这就是volatile
阻止编译器优化代码的方式。现在搜索网络以查看一些示例。
引用 C++ 标准 ($7.1.5.1/8)
[..] volatile 是对 实施以避免激进 涉及对象的优化 因为对象的值可能 通过无法检测到的方式被改变 实施。[...]
相关话题:
Does making a struct volatile make all its members volatile?
【讨论】:
补充一点很重要,volatile
是一个限定符,类似于const
(但当然有不同的含义)所以你也可以声明只能在@ 上调用的volatile
方法987654339@ 个实例。
@Maxpm : 否。extern
关键字用于其他用途。
根据您的示例,编译器似乎在这里很好地优化了代码,因为我猜在 while 函数内部它不会改变 some_int 的值。您能否解释一下 some_int 值发生变化的任何情况?如果不是,那么在这个例子中 volatile 的用途是什么?
很好的答案,最好提一下,在示例中, some_int 的值可以由另一个线程或中断例程更改,作为代码将失败的两个示例,只是为了澄清。 (@dearvivekkumar - 这应该回答你的评论)
@user180574:我认为没有人有时间拿出示例代码来验证这个概念,因为这是一项艰巨的任务。请注意,volatile
的 absence 并不能保证变量的 加载 将被优化掉。只是volatile
的 presence 确保 它没有被优化掉,即使没有关键字也很有可能;不同的是,absence 并不能保证。以上是关于为啥我们使用 volatile 关键字? [复制]的主要内容,如果未能解决你的问题,请参考以下文章