C#中volatile
关键字的用途是什么?
我需要在哪里使用此关键字?
我看到以下声明,但我无法理解为什么这里需要volatile
?
internal volatile string UserName;
答案 0 :(得分:28)
我将引用您的规范10.5.3节,其中指出:
对于非易失性字段,优化 重新排序指令的技术 会导致意外和 不可预知的结果 访问的多线程程序 没有同步的字段,例如 由lock语句提供的 (§8.12)。这些优化可以 由编译器执行,由 运行时系统,或硬件。对于 易变的领域,这种重新排序 优化受到限制:
一个 读取volatile字段称为a 易读。易失性读取有 “获得语义学”;就是这样 保证在任何之前发生 对之后发生的内存的引用 它在指令序列中。
一个 写一个易失性字段称为a 易失写。易失性写入 “释放语义”;就是这样 保证在任何记忆之后发生 写入之前的参考 指令中的指令 序列。
这些限制可确保 所有线程都会观察到volatile 由任何其他线程执行的写入 按照他们的顺序 执行。一致的实施 不需要提供单个 易失写入的总排序为 从所有执行线程中看到。
如果您有意创建一个易变的字段,请非常仔细地阅读 。如果您没有完全彻底了解易失性语义的所有含义,那么请不要尝试使用它们。使用锁通常要好得多,它会自动为您提供足够的内存屏障,以确保必要的获取和释放语义。请记住,当争用时,锁只会非常昂贵。
答案 1 :(得分:7)
Volatile用于在代码运行时无需操作即可更改的变量。它告诉编译器以不会缓存变量的方式编写程序集,而是确保在每次使用之前读取它。
一个易失性的例子是你的代码有内存映射的硬件寄存器,它正在读取以确定何时设置了一个标志。硬件可能会在代码运行时设置值,而不使用volatile关键字,您不会注意到此更改,因为程序集实际上不会检查该值。
答案 2 :(得分:6)
Volatile是编译器(和ngen / jit编译器)的一个暗示,这个变量的值随时都可以改变,因此禁用通过缓存本地volatile的值来访问变量的优化。
请考虑以下代码:
If (UserName == "")
// do something
If (UserName == "Fred")
// do something
如果volatile不存在,编译器可能会生成IL,它会将引用存储在堆栈中以进行第一次比较,而不是将其重用于第二次比较。但是,添加volatile会告诉编译器引用可能会被另一个线程更改,从而迫使它生成不会重复使用第一次比较的堆栈副本的IL。
答案 3 :(得分:4)
“volatile关键字表示某个字段可能被同时执行的多个线程修改。声明为volatile的字段不受编译器优化的影响,这些优化假定单个线程访问。这可以确保最多日期值始终存在于该字段中。“
http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx
答案 4 :(得分:3)
它表示该值可能会被另一个线程更改,因此即使前一条指令已经读取了该值,也需要读取该值。
http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx
答案 5 :(得分:2)
这只是告诉编译器这个变量 将通过任何方式随时改变其价值 编译器不应该对这个变量做任何假设。
通常编译器会假设某个变量是 运行期间常量。这可能会导致检查错误 registor值反复。因为寄存器值可能 什么都改变了。所以对于这些变量 应该被声明为“易变”并且每次都要进行检查 出现在代码中没有任何假设。