“易失性”的目的是什么? C# 中的关键字

发布于 2024-09-30 16:50:15 字数 185 浏览 1 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

怎会甘心 2024-10-07 16:50:15

我建议您参阅规范的第 10.5.3 节,其中规定:

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

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

一个
易失性字段的写入称为
易失性写入。易失性写入有
“释放语义”;也就是说,它是
保证在任何记忆之后发生
写之前的参考文献
指令中的指令
顺序。

这些限制确保
所有线程都会观察到易失性
由任何其他线程执行的写入
按照它们的顺序
执行。符合要求的实施
不需要提供单一
易失性写入的总排序为
从所有执行线程可见。

如果您打算创建一个易失性字段,请非常仔细地阅读该内容。如果您没有完全彻底理解易失性语义的所有含义,那么就不要尝试使用它们。通常使用锁要好得多,它会自动为您提供足够的内存屏障以确保必要的获取和释放语义。请记住,锁只有在发生争用时才真正昂贵。

I refer you to section 10.5.3 of the specification, which states:

For non-volatile fields, optimization
techniques that reorder instructions
can lead to unexpected and
unpredictable results in
multi-threaded programs that access
fields without synchronization such as
that provided by the lock-statement
(§8.12). These optimizations can be
performed by the compiler, by the
run-time system, or by hardware. For
volatile fields, such reordering
optimizations are restricted:

A
read of a volatile field is called a
volatile read. A volatile read has
“acquire semantics”; that is, it is
guaranteed to occur prior to any
references to memory that occur after
it in the instruction sequence.

A
write of a volatile field is called a
volatile write. A volatile write has
“release semantics”; that is, it is
guaranteed to happen after any memory
references prior to the write
instruction in the instruction
sequence.

These restrictions ensure
that all threads will observe volatile
writes performed by any other thread
in the order in which they were
performed. A conforming implementation
is not required to provide a single
total ordering of volatile writes as
seen from all threads of execution.

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.

一人独醉 2024-10-07 16:50:15

易失性用于表示在代码运行时无需您执行任何操作即可更改的变量。它告诉编译器以永远不会缓存变量的方式编写程序集,而是确保在每次使用之前读取它。

易失性的一个例子是您的代码已映射内存并正在读取以确定何时设置标志的硬件寄存器。硬件可能会在代码运行时设置该值,如果不使用 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.

も星光 2024-10-07 16:50:15

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

考虑以下代码:

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

如果 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 (UserName == "")
    // do something
If (UserName == "Fred")
    // do something

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.

携君以终年 2024-10-07 16:50:15

MSDN会比我总结得更好......

“易失性关键字表示一个字段可能会被同时执行的多个线程修改。声明为易失性的字段不受假设由单个线程访问的编译器优化的影响。这确保了最多- 字段中始终存在最新值。”

http://msdn.microsoft.com/en-我们/库/x13ttww7(v=VS.100).aspx

MSDN will summarize better than I....

"The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times."

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

鹿港巷口少年归 2024-10-07 16:50:15

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

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

风情万种。 2024-10-07 16:50:15

它只是告诉编译器这个变量
会随时通过任何方式改变其价值
编译器不应对此变量做出任何假设。

通常编译器会假设某些变量将是
运行期间恒定。这可能会导致检查错误
重复寄存器值。因为寄存器值可能
会被任何事情改变。所以对于这些变量
应该声明为“易失性”并且每次都进行检查
出现在代码中,没有任何假设。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文