Разница между Monitor.Pulse и Monitor.PulseAll - PullRequest
27 голосов
/ 24 марта 2009

Monitor.PulseAll уведомляет всех ожидающих потоков в очереди.

Monitor.Pulse уведомляет о потоке в очереди ожидания. (Следующая ожидающая тема)

Только следующий поток (один поток) может получить блокировку. Так в чем же разница?

Когда я должен использовать Pulse против PulseAll?

Ответы [ 2 ]

43 голосов
/ 24 марта 2009

Используйте PulseAll, если вы хотите активировать несколько потоков, потому что условие, которое они ждут, теперь может быть выполнено для нескольких потоков. (Ожидание почти всегда связано с условием - вы обычно должны проверять это условие в цикле while.)

Используйте Pulse, когда вы хотите разбудить только один поток, потому что только один поток действительно сможет выполнять полезную работу.

Чтобы привести две аналогии:

Представьте, что у вас есть один принтер. Только один человек может использовать его одновременно, поэтому, если вас ждет много людей, вы отправляете их всех спать, но вы разбудите только одного человека, когда принтер освободится. Это отражает использование Pulse.

Теперь представьте, что вы управляете магазином. Пока вы закрыты, клиенты ждут снаружи магазина. Когда вы открываете магазин, вы не просто хотите разбудить одного покупателя - все они могут прийти сейчас. Это отражает использование PulseAll.

34 голосов
/ 24 марта 2009

A Monitor имеет две очереди: очередь ожидания и очередь готовности. При отсутствии Wait и Pulse все потоки, которые пытаются получить блокировку, попадают в очередь готовности. Когда блокировка станет доступной, один поток из очереди готовности получит ее.

Когда поток получает блокировку, а затем выполняет Wait, этот поток попадает в очередь ожидания. Он ожидает Pulse или PulseAll и будет оставаться в очереди ожидания, пока не получит Pulse, даже если другие потоки из очереди готовности получат и снимают блокировку.

Pulse перемещает один поток из очереди ожидания в очередь готовности. PulseAll перемещает ВСЕ потоки из очереди ожидания в очередь готовности.

Ключевым моментом здесь является то, что потоки в очереди ожидания никогда не смогут получить блокировку. Они ждут импульса, чтобы переместить их обратно в очередь готовности, чтобы они могли получить блокировку, когда она станет доступной.

Есть довольно хорошее обсуждение Wait и Pulse - по крайней мере, немного, чтобы вы начали - здесь .

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