具有释放/获取语义的易失性
从 Java 5 开始,易失性
关键字具有释放/获取语义,以使副作用对其他线程可见(包括对非易失性变量的赋值!)。以这两个变量为例:
int i;
volatile int v;
请注意,i
是一个常规的非易失性变量。假设线程 1 执行以下语句:
i = 42;
v = 0;
在稍后的某个时间点,线程 2 执行以下语句:
int some_local_variable = v;
print(i);
根据 Java 内存模型,线程 1 中写入 v
后读取v 确保线程 2 看到线程 1 中执行的对
i
的写入,因此打印值 42。
我的问题是:在 C# 中,易失性
是否具有相同的释放/获取语义?
Since Java 5, the volatile
keyword has release/acquire semantics to make side-effects visible to other threads (including assignments to non-volatile variables!). Take these two variables, for example:
int i;
volatile int v;
Note that i
is a regular, non-volatile variable. Imagine thread 1 executing the following statements:
i = 42;
v = 0;
At some later point in time, thread 2 executes the following statements:
int some_local_variable = v;
print(i);
According to the Java memory model, the write of v
in thread 1 followed by the read of v
in thread 2 ensures that thread 2 sees the write to i
executed in thread 1, so the value 42 is printed.
My question is: does volatile
have the same release/acquire semantics in C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
C# 中“易失性”的语义在 C# 6.0 规范。我鼓励您在规范中查找它,而不是在这里重现它们,然后确定使用“易失性”太复杂和危险,然后返回使用锁。这就是我一直做的事情。
请参阅“ 7.10 执行顺序”和“14.5.4 易失性字段< /a>”在 C# 6.0 规范中。
在 C# 5.0 规范中,请参阅“3.10 执行顺序”和“10.5.3 易失性字段”
The semantics of "volatile" in C# are defined in sections 7.10 and 14.5.4 of the C# 6.0 specification. Rather than reproduce them here, I encourage you to look it up in the spec, and then decide that it is too complicated and dangerous to use "volatile", and go back to using locks. That's what I always do.
See "7.10 Execution order" and "14.5.4 Volatile fields" in the C# 6.0 specification.
In the C# 5.0 specification, see "3.10 Execution Order" and "10.5.3 Volatile Fields"
好吧,我相信它可以确保 if
some_local_variable
被读取为0
(由于写入v
),i
将被读取为 42。棘手的部分是“在稍后的某个时间点”。虽然波动性通常是通过“刷新”写入来讨论的,但这并不是规范中实际定义的方式(Java 或 C#)。
来自 C# 4 语言规范,第 10.5.3 节:
然后有一个与您的示例非常相似的示例,但条件是从 volatile 变量读取的值。
和 Eric 一样,我自己也强烈避免依赖 volatility。这很难推理,最好留给世界上的乔·达菲/斯蒂芬·图布斯。
Well, I believe it ensures that if
some_local_variable
is read as0
(due to the write tov
),i
will be read as 42.The tricky part is "at some later point in time". While commonly volatility is talked about in terms of "flushing" writes, that's not how it's actually defined in the spec (either Java or C#).
From the C# 4 language spec, section 10.5.3:
There's then an example which is quite similar to yours, but conditional on the value read from the volatile variable.
And like Eric, I'd strongly avoid relying on volatile myself. It's hard to reason about, and best left to the Joe Duffy/Stephen Toubs of the world.