Roy*_*mir 23 .net c# multithreading volatile thread-safety
根据MSDN:
volatile关键字表示某个字段可能被同时执行的多个线程修改.声明为volatile的字段不受编译器优化的约束,这些优化假定由单个线程进行访问.这可确保始终在字段中显示最新值.
请注意最后一句:
这可确保始终在字段中显示最新值.
但是,此关键字存在问题.
我已经读过它可以改变指令的顺序:
Run Code Online (Sandbox Code Playgroud)First instruction Second instruction Can they be swapped? Read Read No Read Write No Write Write No Write Read Yes! <----
这意味着John为一个易变的字段设置了一个值,后来 Paul想要阅读该字段,Paul正在获得旧的价值!
这是怎么回事?这不是主要的工作吗?
我知道还有其他解决方案,但我的问题是关于volatile关键字.
我(作为程序员)是否需要阻止使用此关键字 - 因为这种奇怪的行为?
Til*_*lak 18
那你是对的.在Joseph Albahari线程书/文章中更详细说明.
MSDN文档指出使用volatile关键字可确保始终在字段中显示最新值.这是不正确的,因为正如我们所见,可以重新排序读取后跟读取.
http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword
我(作为程序员)是否需要阻止使用此关键字 - 因为这种奇怪的行为?
只有在知道了这种习惯行为后才能使用它.它不应该用作Magic关键字来在多线程环境中始终检索最新值.
IMO,应避免使用volatile关键字,因为很难找到可能的错误.
MSDN文档是错误的.这肯定不是什么volatile
.C#规范确切地告诉你什么volatile
,并且获得"新读"或"提交写入"不是其中之一.规范是正确的.volatile
只保证在写入时读取和释放围栏上的获取范围.这些定义如下.
我将尝试使用箭头符号解释表格.↓箭头将标记易失性读数,↑箭头将标记易失性写入.没有指令可以通过箭头移动.把箭头想象成推开一切.
在下面的分析中,我将使用变量; x
和y
.我还假设他们被标记为volatile
.
情况1
注意读取后箭头的放置如何x
防止读取y
向上移动.另请注意,y
在这种情况下,波动性无关紧要.
var localx = x;
?
var localy = y;
?
Run Code Online (Sandbox Code Playgroud)
案例#2
请注意读取后箭头的放置如何x
防止写入y
向上移动.另请注意,在这种情况下,可以省略x
或y
不是两者的波动性.
var localx = x;
?
?
y = 1;
Run Code Online (Sandbox Code Playgroud)
案例#3
注意在写入之前放置箭头是如何y
防止写入x
向下移动的.请注意,x
在这种情况下,波动性无关紧要.
?
x = 1;
?
y = 2;
Run Code Online (Sandbox Code Playgroud)
案例#4
请注意,写入x
和读取之间没有障碍y
.因此,写入x
可以向下浮动或读取y
可以浮动.这两种运动都是有效的.这就是为什么可以交换写 - 读案例中的指令.
?
x = 1;
var localy = y;
?
Run Code Online (Sandbox Code Playgroud)
值得注意的提及
同样重要的是要注意:
归档时间: |
|
查看次数: |
1159 次 |
最近记录: |