假设我们有以下代码:
class Program
{
static volatile bool flag1;
static volatile bool flag2;
static volatile int val;
static void Main(string[] args)
{
for (int i = 0; i < 10000 * 10000; i++)
{
if (i % 500000 == 0)
{
Console.WriteLine("{0:#,0}",i);
}
flag1 = false;
flag2 = false;
val = 0;
Parallel.Invoke(A1, A2);
if (val == 0)
throw new Exception(string.Format("{0:#,0}: {1}, {2}", i, flag1, flag2));
}
}
static void A1()
{
flag2 = true;
if (flag1)
val = 1;
}
static void A2()
{
flag1 = true;
if (flag2)
val = 2;
}
}
}
都是错!主要问题是为什么...我认为 CPU 对 flag1 = true 的操作进行重新排序;和 if(flag2) 语句,但变量 flag1 和 flag2 标记为易失性字段...
在.NET内存模型中,运行时(CLI)将确保对易失性字段的更改不会缓存在寄存器中,因此任何线程上的更改都会立即在其他线程上看到(NB这在其他内存模型(包括 Java 的内存模型)中并非如此。
但这并没有说明跨多个(无论是否不稳定)字段的操作的相对顺序。
为了在多个字段之间提供一致的排序,您需要使用锁(或内存屏障,显式或隐式地使用包含内存屏障的方法之一)。
欲了解更多详情,请参阅
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)