当应volatile关键字在C#中使用?

当应volatile关键字在C#中使用?

问题描述:

任何人都可以提供C#中的volatile关键字的一个很好的解释?哪些问题它解决和它不?在这种情况下,将其救我用锁定?

Can anyone provide a good explanation of the volatile keyword in C#? Which problems does it solve and which it doesn't? In which cases will it save me the use of locking?

我不认为有一个更好的人来回答这个比Eric利珀特(在原重点):

I don't think there's a better person to answer this than Eric Lippert (emphasis in the original):

在C#中,挥发性不仅意味着确保编译器和
  抖动不执行任何code重新排序或注册缓存
  此变量的优化。这也意味着告诉处理器
  做到不管它是什么,他们需要做什么来确保我读了
  最新值,即使这意味着停止其它处理器和制作
  它们进行同步与他们的高速缓存主存。

In C#, "volatile" means not only "make sure that the compiler and the jitter do not perform any code reordering or register caching optimizations on this variable". It also means "tell the processors to do whatever it is they need to do to ensure that I am reading the latest value, even if that means halting other processors and making them synchronize main memory with their caches".

其实,这最后一点是骗人的。挥发性读取真正的语义
  和写入复杂得多,比我在这里列出;在
  事实上它们实际上并不保证每一个处理器停止它
  是做
并更新缓存来/从主内存。相反,他们提供
  关于内存之前,如何访问和读取之后,和较弱的担保
  可观察到的写入相对于彼此强>订购。
  某些操作,如创建一个新的线程,进入了一个锁,或
  使用方法的互锁家族中的一强介绍
  有关订购的观察保证。如果您想了解更多的细节,
  阅读部分3.10和C#4.0规范的10.5.3。

Actually, that last bit is a lie. The true semantics of volatile reads and writes are considerably more complex than I've outlined here; in fact they do not actually guarantee that every processor stops what it is doing and updates caches to/from main memory. Rather, they provide weaker guarantees about how memory accesses before and after reads and writes may be observed to be ordered with respect to each other. Certain operations such as creating a new thread, entering a lock, or using one of the Interlocked family of methods introduce stronger guarantees about observation of ordering. If you want more details, read sections 3.10 and 10.5.3 of the C# 4.0 specification.

坦率地说,我不鼓励你永远做一个volatile字段。挥发物
  字段是你正在做的事情简直是疯狂的​​一个标志:你
  试图读取并在两个不同的线程相同的值写入
  没有把锁到位。锁保证内存读取或
  在锁内修改的观察是一致的,保证锁定
  只有一个线程在同一时间访问给定内存大块,所以
  上。其中一个锁定太慢的情况的数量是非常
  小,而且,你会得到code错误的概率
  因为你不知道确切的内存模型是非常大的。一世
  不要尝试写入任何低锁定code除了最琐碎
  互锁操作的用法。我离开的挥发性的用法
  真正的专家。

Frankly, I discourage you from ever making a volatile field. Volatile fields are a sign that you are doing something downright crazy: you're attempting to read and write the same value on two different threads without putting a lock in place. Locks guarantee that memory read or modified inside the lock is observed to be consistent, locks guarantee that only one thread accesses a given hunk of memory at a time, and so on. The number of situations in which a lock is too slow is very small, and the probability that you are going to get the code wrong because you don't understand the exact memory model is very large. I don't attempt to write any low-lock code except for the most trivial usages of Interlocked operations. I leave the usage of "volatile" to real experts.

进一步的阅读可见:

  • Understand the Impact of Low-Lock Techniques in Multithreaded Apps
  • Sayonara volatile