4

假设我们有以下代码:

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 标记为易失性字段...

4

2 回答 2

5

在 .NET 内存模型中,运行时 (CLI) 将确保对 volatile 字段的更改不会缓存在寄存器中,因此任何线程上的更改都会立即在其他线程上看到(注意这在其他内存模型中并非如此,包括 Java 的)。

但这并没有说明跨多个可变或非可变字段的操作的相对顺序。

要跨多个字段提供一致的排序,您需要使用锁(或内存屏障,显式或隐式地使用包含内存屏障的方法之一)。

有关更多详细信息,请参阅“Windows 上的并发编程”,Joe Duffy,AW,2008

于 2010-04-15T12:40:28.223 回答
2
于 2017-08-04T08:31:47.283 回答