7

このプログラムは 2 つの異なるスレッドを実行し、「レース」の勝者を教えてくれます。

予想外に、両方のスレッドが「勝つ」ことがあります(誰かが勝つか、誰も勝てないと思っていました)。これは予想される動作で、その理由は何ですか? ここで明らかに基本的なことが欠けています。

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を読んで理解してからもう一度読むことをお勧めします

追加: .NET 4
のクラスをブラウズしたところ、キーワードが使用されている場所はありません。 また、何らかの理由でループする前に配列をコピーしますが、それがあなたに影響を与えるとは思えません。Parallelvolatile
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 に答える