Теперь мне кажется, что функционально Semaphore.WaitOne/Release
равно Monitor.Wait/Pulse
. Пропуск межпроцессорных возможностей, скорость (да, монитор управляется) другие нефункциональные различия, что такое реальная разница?
Semaphore.WaitOne/Release vs Monitor.Pulse/Wait
Ответ 1
Основной целью Semaphore
является управление доступом к конечному набору ресурсов. Тема может участвовать в приобретении resouce, вызывая WaitOne
и Release
. Тед должен вызвать WaitOne
для получения ресурса. Тем не менее, он будет блокироваться только в том случае, если счет семафора достигнет 0, иначе поток можно будет немедленно получить. Как только этот поток будет завершен, он должен вызвать Release
, чтобы сигнализировать семафор, что дополнительный слот был освобожден для другого потока.
Monitor.Wait
и Monitor.Pulse
сильно различаются. В первую очередь не учитывается счет. Если Pulse
вызывается в отсутствие какого-либо вызова Wait
, тогда сигнал игнорируется и отбрасывается. Он не ставится в очередь так же, как семафор. На самом деле поведение Wait
и Pulse
вообще не имеет смысла. Wait
просто ждет изменения состояния приобретенной блокировки (полученной из Monitor.Enter
). Pulse
- это сигнал, что что-то изменилось. Вот почему вы часто видите Wait
, вызванный в цикле while
. Ожидающий поток должен повторить условие ожидания, потому что он не знает, что изменилось!
Monitor.Wait
и Monitor.Pulse
являются фундаментальными механизмами синхронизации, которые могут использоваться для создания практически любого другого устройства синхронизации, включая семафоры.
Ответ 2
Monitor.Wait/Pulse предоставляет вам переменную условия, которая больше похожа на событие auto- reset, чем семафор (но не точно). Основное различие заключается в том, что семафор имеет счет, что означает, что вам не нужно ничего блокировать, чтобы вы не пропустили пульс (в отличие от Monitor.Wait).