0

ThreadAとThreadBの両方WaitOne()が同じAutoResetEventでこの順序で呼び出すと仮定します。イベントが設定されている場合、なぜThreadAではなくThreadBがリリースされるのですか?

複数のスレッドが待機しているAutoResetEventを設定するとどうなるかを調べるために、テストを実行しました。

    private static void Test()
    {
        // two threads - waiting for the same autoreset event
        // start it unset i.e. closed i.e. anything calling WaitOne() will block
        AutoResetEvent autoEvent = new AutoResetEvent(false);

        Thread thread1 = new Thread(new ThreadStart(WriteSomeMessageToTheConsole));
        thread1.Start();  // this will now block until we set the event

        Thread thread2 = new Thread(new ThreadStart(WriteSomeOtherMessageToTheConsole));
        thread2.Start();  // this will now also block until we set the event

        // simulate some other stuff
        Console.WriteLine("Doing stuff...");
        Thread.Sleep(5000);
        Console.WriteLine("Stuff done.");

        // set the event - I thought this would mean both waiting threads are allowed to continue
        // BUT thread2 runs and thread1 stays blocked indefinitely
        // So I guess I was wrong and that Set only releases one thread in WaitOne()?
        // And why thread2 first?
        autoEvent1.Set();
    }

もちろん、このコードは役に立ちません。ミッキーマウスの例です。そして、これは重要/緊急ではありません。しかし、とにかくもっと知りたいと思います...

4

3 に答える 3

2

自動リセットイベントによって解放されるスレッドであるIIRCは指定されていません。他のみんなが言ったように、条件をブロードキャストしたい場合は、手動リセットイベントが必要です。正確な数(たとえば、nの正確に3)を解放したい場合は、おそらくセマフォを使用する必要があります。

順序が予想と異なる理由を本当に詳しく知りたい場合は、「WindowsInternals」またはMarkRussinovichが書いたものをご覧ください。彼はどこかでエグゼクティブリソースの待機順序を説明している可能性があります。

于 2009-04-10T00:44:21.930 に答える
1

MSDNから

ManualResetEventに関するMSDN: "ManualResetEventでWaitOneを呼び出すスレッドはブロックされ、シグナルを待機します。制御スレッドがアクティビティを完了すると、Setを呼び出して、待機中のスレッドが続行できることを通知します。 待機中のスレッドはすべて解放されます。

ただし、AutoResetEventの場合、MSDNは次のように述べてい ます

「」

于 2009-04-10T00:36:53.663 に答える
0

AutoResetEvent、Setは1つのスレッドのみを解放します。ManualResetEventを使用して、複数の待機中のスレッドを解放する必要があります。

于 2009-04-10T00:17:35.767 に答える