“易失性”的目的是什么? C# 中的关键字
C# 中 volatile
关键字的用途是什么?
我需要在哪里使用这个关键字?
我看到了下面的语句,但我无法理解为什么这里需要 volatile
?
internal volatile string UserName;
What is the purpose of volatile
keyword in C#?
Where would I need to use this keyword?
I saw the following statement, but I am unable to understand why volatile
is required here?
internal volatile string UserName;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我建议您参阅规范的第 10.5.3 节,其中规定:
如果您打算创建一个易失性字段,请非常仔细地阅读该内容。如果您没有完全彻底理解易失性语义的所有含义,那么就不要尝试使用它们。通常使用锁要好得多,它会自动为您提供足够的内存屏障以确保必要的获取和释放语义。请记住,锁只有在发生争用时才真正昂贵。
I refer you to section 10.5.3 of the specification, which states:
Read that extremely carefully if you have any intention of ever making a volatile field. If you do not completely and thoroughly understand all the implications of volatile semantics then do not attempt to use them. It is usually far better to use a lock, which automatically gives you sufficient memory barriers to ensure the necessary acquire and release semantics. Remember, locks are only really expensive when they are contended.
易失性用于表示在代码运行时无需您执行任何操作即可更改的变量。它告诉编译器以永远不会缓存变量的方式编写程序集,而是确保在每次使用之前读取它。
易失性的一个例子是您的代码已映射内存并正在读取以确定何时设置标志的硬件寄存器。硬件可能会在代码运行时设置该值,如果不使用 volatile 关键字,您将不会注意到此更改,因为程序集不会实际检查该值。
Volatile is used for a variable that can change without your action while your code is running. It tells the compiler to write the assembly in such a way as to not ever cache the variable, but to instead be sure to read it before every use.
An example of something that would be volatile would be a hardware register that your code has memory mapped and is reading to determine when a flag is set. The hardware may set the value while your code is running and without using the volatile keyword you would not notice this change as the assembly would not ever actually check the value.
Volatile 是对编译器(和 ngen/jit 编译器)的提示,该变量的值可以随时更改,因此通过在本地缓存 volatile 值来访问变量的优化被禁用。
考虑以下代码:
如果 volatile 不存在,编译器可能会生成 IL,其中它将引用存储在堆栈上以进行第一次比较,然后在第二次比较中重用它。但是,添加 volatile 告诉编译器该引用可能会被另一个线程更改,从而强制它生成不会重用第一次比较中的堆栈副本的 IL。
Volatile is a hint for the compiler (and ngen/jit compiler) that the value of this variable can change at any moment, and thus optimizations around accessing the variable by caching the value locally volatile be disabled.
Consider the following code:
If volatile was not present, the compiler might generate IL where it stores the reference on the stack for the first comparison and than reuses it for the second one. However, adding volatile tells the compiler that the reference might be changed by another thread, thus forcing it to generate IL that will not reuse the stack copy from the first comparison.
MSDN会比我总结得更好......
http://msdn.microsoft.com/en-我们/库/x13ttww7(v=VS.100).aspx
MSDN will summarize better than I....
http://msdn.microsoft.com/en-us/library/x13ttww7(v=VS.100).aspx
它表明该值可能会被不同的线程更改,因此即使先前的指令已经读取了该值,也需要读取该值。
http://msdn.microsoft.com/en-us /library/x13ttww7%28VS.71%29.aspx
It indicates that the value may get changed by a different thread, so the value needs to be read even if a previous instruction has already read it.
http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.71%29.aspx
它只是告诉编译器这个变量
会随时通过任何方式改变其价值
编译器不应对此变量做出任何假设。
通常编译器会假设某些变量将是
运行期间恒定。这可能会导致检查错误
重复寄存器值。因为寄存器值可能
会被任何事情改变。所以对于这些变量
应该声明为“易失性”并且每次都进行检查
出现在代码中,没有任何假设。
It is nothing but telling to compiler that this variable
will change its value at anytime by means of anything and
compiler should not make any assumption about this variable.
Normally compiler will assume that some variable will be
constant during runtime. This may lead error in checking a
registor value repeatedly. Because the register value may
be changed by anything. So for these kind of variables
should be declared 'volatile' and it be checked each time
appears in the code with out any assumption.