7

该程序执行两个不同的线程,并告诉我“比赛”的获胜者是谁。

出乎意料的是,有时两个线程都“获胜”(我希望有人或没有人获胜)。这是预期的行为,为什么?我显然在这里遗漏了一些基本的东西。

class Program
{
    public volatile static int a = 0; 
    public volatile static int b = 0;

    public static void Main()
    {
        for(int i = 0; i < 1000; i++)
        {
            a = 0; 
            b = 0;

            Parallel.Invoke(delegate { a = 1; if (b == 0) Console.WriteLine("A wins"); },
                            delegate { b = 1; if (a == 0) Console.WriteLine("B wins"); });

            Console.WriteLine(System.Environment.NewLine);

            Thread.Sleep(500);
        }
    }
}

结果:

A wins

B wins

A wins
B wins

A wins

...
4

2 回答 2

3

您错误地使用了 volatile:

声明变量 volatile 是不够的,您需要确保在您读/写它们的任何地方Thread.VolatileRead(ref myVar)都使用/Thread.VolatileWrite(ref myVar)

此外,即使正确使用, volatile 也不能确保读/写顺序(来自不同的线程)。浏览 SO 以获取有关该主题的信息。编辑:它似乎在 x86 单核机器上做

您可以简单地使用该lock声明,但如果您想深入了解,我建议您阅读、理解,然后再阅读这本免费的电子书

补充:
我刚刚浏览了Parallel.NET 4 中的类,没有使用volatile关键字。由于某种原因,他们还在循环之前
复制了数组,但我怀疑这会影响你。Action<T>

于 2012-10-04T11:46:27.097 回答
1

当它们并行执行时,两者都获胜。

从文档(http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.invoke.aspx):执行每个提供的操作,可能并行

于 2012-10-04T10:56:51.290 回答