小编典典

什么时候应该在 C# 中使用 volatile 关键字?

all

谁能很好地解释 C# 中的 volatile 关键字?它解决了哪些问题,没有解决哪些问题?在哪些情况下它会节省我使用锁定的时间?


阅读 95

收藏
2022-04-02

共1个答案

小编典典

我认为没有比Eric Lippert更好的人来回答这个问题(强调原文):

在 C#
中,“volatile”不仅意味着“确保编译器和抖动不会对此变量执行任何代码重新排序或注册缓存优化”。这也意味着“告诉处理器做他们需要做的任何事情,以确保我正在读取最新的值,即使这意味着停止其他处理器并使它们与它们的缓存同步主内存”。

实际上,最后一点是谎言。volatile 读写的真正语义比我在这里概述的要复杂得多。事实上
,它们实际上并不能保证每个处理器都会停止它正在做的事情 并更新缓存到主内存/从主内存更新。相反,
它们提供了较弱的保证,即可以观察到读取和写入之前和之后的内存访问如何相对于彼此进行排序 。某些操作(例如创建新线程、进入锁或使用
Interlocked 系列方法之一)会为观察排序引入更强的保证。如果您想了解更多详细信息,请阅读 C# 4.0 规范的第 3.10 和 10.5.3
节。

坦率地说, 我不鼓励你创建一个 volatile field
。易失性字段表明您正在做一些彻头彻尾的疯狂事情:您试图在两个不同的线程上读取和写入相同的值而没有设置锁定。锁保证观察到锁内的内存读取或修改是一致的,锁保证一次只有一个线程访问给定的内存块,等等。锁太慢的情况很少,因为不了解确切的内存模型而导致代码出错的可能性很大。除了互锁操作的最琐碎用法之外,我不会尝试编写任何低锁代码。我将“易失性”的用法留给真正的专家。

2022-04-02