Interlocked.MemoryBarrierProcessWide() 如何更改多核中的执行顺序?

How does Interlocked.MemoryBarrierProcessWide() change the execution order in multicore?

提问人:user22155685 提问时间:11/7/2023 最后编辑:Theodor Zouliasuser22155685 更新时间:11/7/2023 访问量:22

问:

如果我们以发布模式运行以下代码

class Program
{
    static volatile int x, y, a, b;
    static void Main()
    {
        while (true)
        {
            var t1 = Task.Run(Test1);
            var t2 = Task.Run(Test2);
            Task.WaitAll(t1, t2);
            if (a == 0 && b == 0)
            {
                Console.WriteLine("{0}, {1}", a, b);
            }
            x = y = a = b = 0;
        }
    }

    static void Test1()
    {
        x = 1; 
        //Interlocked.MemoryBarrierProcessWide()   comment out first
        a = y;
    }

    static void Test2()
    {
        y = 1;
        b = x;
    }
}

我们可以看到很多 0,0 打印出来,因为我们不使用任何内存障碍。 但是,如果我们使用(取消注释),那么我们将看不到任何 0,0 输出。Interlocked.MemoryBarrierProcessWide()

但是,如果我将顺序更改为Test2

class Program
{
    static volatile int x, y, a, b;
    static void Main()
    {
        while (true)
        {
            var t1 = Task.Run(Test1);
            var t2 = Task.Run(Test2);
            Task.WaitAll(t1, t2);
            if (a == 0 && b == 0)
            {
                Console.WriteLine("{0}, {1}", a, b);
            }
            x = y = a = b = 0;
        }
    }

    static void Test1()
    {
        x = 1;   // 2
        Interlocked.MemoryBarrierProcessWide();  // 3
        a = y;   // 4
    }

    static void Test2()
    {

        b = x;   // 1

        y = 1;   // 5
    }
}

我标记了执行顺序,threadA 执行 1,所以是 0,然后发生上下文切换 threadB 执行 2,3,4,执行 4 后,是 0,然后 threadA 连续执行 5。所以我们应该打印 0,0,但没有,这是为什么?Interlocked.MemoryBarrierProcessWide() 如何更改执行顺序,以便没有 0,0 打印baTest2

static void Test2()
{
   y = 1;
   b = x;
}

static void Test2()
{
   b = x;
   y = 1;   
}
C# .NET 多线程 CLR 互锁

评论

2赞 JonasH 11/7/2023
你似乎认为有任何全局排序。这是错误的,CPU 一直在并发做事。指令按顺序运行的虚构仅对单个线程有效。我认为您的示例并不能证明太多,即使从未打印过 0,0,0,它仍然可能有问题。多线程程序因仅在您最不希望它们失败时才失败而臭名昭著。我建议使用锁来保证订购。内存屏障通常是相当专用的同步基元,MemoryBarrierProcessWide 更是如此。

答: 暂无答案