For me now it looks like functionally Semaphore.WaitOne/Release
is equal to Monitor.Wait/Pulse
. Skipping interprocess capabilities, speed (yes, Monitor is managed) other nonfunctional differences, what is real difference then?
The main purpose of a Semaphore
is to control access to a finite set of resources. Thread can participate in resouce acquisition by calling WaitOne
and Release
. A thead should call WaitOne
to acquire the resource. However, it will only block if the semaphore's count reaches 0 otherwise the thread is free to acquire immediately. Once that thread is finished it should call Release
to signal the semaphore that an extra slot has been freed up for another thread.
Monitor.Wait
and Monitor.Pulse
are drastically different. First and foremost there is no counting involved. If Pulse
is called in the absence of any call to Wait
then the signal is ignored and discarded. It is not queued up in the same way that a semaphore would. In fact, the behavior of Wait
and Pulse
has no inherent meaning at all. The Wait
is simply waiting for a change in the state of the acquired lock (acquired from Monitor.Enter
). The Pulse
is the signal that something changed. That is why you often see Wait
called in a while
loop. The waiting thread must retest the wait condition because it has no idea what changed!
Monitor.Wait
and Monitor.Pulse
are fundamental synchronization mechanisms that can be used to form pretty much any other synchronization device including semaphores.
Monitor.Wait/Pulse provides you with a condition variable, which is more like an auto-reset event than a semaphore (but not exactly). The main difference is that a semaphore has a count, which means you don't need to lock anything in order to ensure you don't miss a pulse (unlike with Monitor.Wait).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With