Dekker算法混淆的变体

时间:2012-10-04 10:47:56

标签: c# multithreading concurrency parallel-processing

这个程序执行两个不同的线程并告诉我“种族”的赢家是谁。

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

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

...

2 个答案:

答案 0 :(得分:3)

您正在使用不正确的wave:

声明变量volatile是不够的,你需要确保无处不在你读/写它们,你使用Thread.VolatileRead(ref myVar) / Thread.VolatileWrite(ref myVar)

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

你可以简单地使用lock声明,但如果你想深究这一点,我建议阅读,理解,然后再读一遍this free e-book

<强>加法:
我刚刚浏览了.NET 4中的Parallel类,并且没有使用volatile关键字。
他们还会复制Action<T>数组,然后出于某种原因循环它,但我怀疑这会影响你。

答案 1 :(得分:1)

两者并行执行时获胜。

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