如何解决为什么指令重新排序以这种方式工作?
我正在 .net framework 45 上运行一个简单的代码片段:
public class Program
{
public static /*volatile*/ int A = 1;
public static int B = 1;
public static bool ReadAndCheck()
{
var a = A;
// Interlocked.MemoryBarrier(); full memory barrier works as expected
var b = B;
return a > b;
}
public static void First()
{
while (true)
{
e.WaitOne();
if (ReadAndCheck())
{
Console.WriteLine("reordering");
}
e.Set();
}
}
private static readonly AutoResetEvent e = new AutoResetEvent(false);
public static void Second()
{
while (true)
{
A = 1;
B = 1;
e.Set();
B = 2;
A = 2;
e.WaitOne();
}
}
public static void Main()
{
new Thread(First).Start();
new Thread(Second).Start();
Console.ReadKey();
}
}
而且我在控制台中收到了很多“重新排序”消息。我假设这是 cpu 执行的指令重新排序。我发现如果我在 First 方法中添加一个 Interlocked.MemoryBarried
(它在那里被注释),代码工作正常并且我的控制台中没有“重新排序”消息。此外,我认为这是因为 var a = A;
和 var b = B;
指令在它们之间重新排序(首先我们读取 B,然后是 A)并且内存屏障确保这些指令的“正确”序列
然后,据我所知,可变字段“A”就足够了,因为它似乎阻止了 var b = B;
在 var a = A
之前执行。但事实上,事实并非如此,我不断收到“错误”消息。任何人都可以澄清这种行为吗?
UPD:
如果使 A
不稳定,我希望半屏障能正常工作。因为在 volatile read 之下的指令不能移动到 volatile read 之上。这意味着,var b = B
永远不会移动到 var a = A
之上。
如果我错了,请随时纠正我
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。