Почему второй поток освобождается раньше первого, когда они оба вызвали WaitOne () и были освобождены AutoResetEvent? - PullRequest
0 голосов
/ 10 апреля 2009

Предположим, что ThreadA и ThreadB оба вызывают WaitOne() в том же порядке в одном и том же AutoResetEvent. Когда событие установлено, почему ThreadB освобождается вместо ThreadA?

Я запустил тест, чтобы выяснить, что происходит, когда вы устанавливаете 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();
    }

Код, конечно, не полезен; это просто пример Микки Мауса. И это не важно / срочно. Но мне все равно было бы интересно узнать больше ...

Ответы [ 3 ]

2 голосов
/ 10 апреля 2009

IIRC, какой поток освобождается событием автосброса, не указано. Как все остальные упоминали, вы хотите событие ручного сброса, если вы хотите передать условие. Если вы хотите выпустить точное число (скажем, точно 3 из n), то вы, вероятно, хотите использовать семафор.

Если вы действительно хотите разобраться, почему порядок может отличаться от ожидаемого, взгляните на «Windows Internals» или что-нибудь, что написал Марк Руссинович. Скорее всего, он где-то объясняет порядок ожидания на исполнительных ресурсах.

1 голос
/ 10 апреля 2009

Из MSDN

MSDN на ManualResetEvent: «Темы что вызов WaitOne на ManualResetEvent заблокирует, ожидая сигнал. Когда контролирующий поток завершает деятельность, это звонки Установите, чтобы сигнализировать, что ожидание темы могут продолжаться. Все ожидающие темы освобождаются.

Но для AutoResetEvent MSDN говорит: "Вызов Set устанавливает сигналы AutoResetEvent для освободить ожидающую ветку AutoResetEvent остается сигнальным до один ожидающий поток освобождается , а затем автоматически возвращается в состояние без сигнала. Если никаких тем не ждут, состояние остается сигнализированным бесконечно.

"

0 голосов
/ 10 апреля 2009

На AutoResetEvent , Set освобождает только один поток. Вы должны использовать ManualResetEvent для освобождения нескольких ожидающих потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...