C#中’volatile’关键字的目的是什么?

在C#中volatile关键字的目的是什么?

我需要在哪里使用此关键字?

我看到了以下声明,但我无法理解为什么需要使用volatile

 internal volatile string UserName; 

我将引用您的规范10.5.3节,其中规定:

对于非易失性字段,重新排序指令的优化技术可能会在multithreading程序中导致意外和不可预测的结果,这些程序无需同步即可访问字段,例如lock-statement(第8.12节)提供的字段。 这些优化可以由编译器,运行时系统或硬件执行。 对于易失性字段,此类重新排序优化受到限制:

读取volatile字段称为volatile读取。 易失性读取具有“获取语义”; 也就是说,保证在指令序列之后的任何内存引用之前发生。

写入易失性字段称为易失性写入。 易失性写入具有“释放语义”; 也就是说,保证在指令序列中的写指令之前的任何存储器引用之后发生。

这些限制确保所有线程将按照执行顺序观察由任何其他线程执行的易失性写入。 从所有执行线程看,不需要符合要求的实现来提供易失写入的单个总排序。

如果您有意创造一个不稳定的领域,请仔细阅读。 如果您没有完全彻底地理解volatile语义的所有含义,那么不要尝试使用它们。 使用锁通常要好得多,它会自动为您提供足够的内存屏障,以确保必要的获取和释放语义。 请记住,当争用时,锁只是非常昂贵。

Volatile用于变量,在代码运行时可以在不执行操作的情况下进行更改。 它告诉编译器以不会缓存变量的方式编写程序集,而是确保在每次使用之前读取它。

一个易失性的例子是你的代码有内存映射的硬件寄存器,它正在读取以确定何时设置了一个标志。 硬件可以在代码运行时设置值,而不使用volatile关键字,您不会注意到此更改,因为程序集实际上不会实际检查该值。

Volatile是编译器(和ngen / jit编译器)的暗示,该变量的值随时都可以更改,因此禁用通过缓存本地volatile的值来访问变量的优化。

请考虑以下代码:

 If (UserName == "") // do something If (UserName == "Fred") // do something 

如果volatile不存在,编译器可能会生成IL,它会将引用存储在堆栈中以进行第一次比较,而不是将其重用于第二次比较。 但是,添加volatile会告诉编译器引用可能会被另一个线程更改,从而迫使它生成不会从第一次比较中重用堆栈副本的IL。

MSDN总结会比我好….

“volatile关键字表示某个字段可能被同时执行的多个线程修改。声明为volatile的字段不受编译器优化的影响,这些优化假定单个线程可以访问。这可以确保最多的线程。日期值始终存在于该字段中。“

http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx

它表示该值可能会被另一个线程更改,因此即使先前的指令已经读取了该值,也需要读取该值。

http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx

它只是告诉编译器这个变量会随时通过任何东西改变它的值,编译器不应该对这个变量做任何假设。

通常编译器会假设某些变量在运行时会保持不变。 这可能导致重复检查寄存器值的错误。 因为寄存器值可能会被任何改变。 因此,对于这些类型的变量,应该声明为“volatile”,并且每次出现在代码中都要进行检查,不做任何假设。