On 2007-10-31 15:51:00 -0700, msdn@comsquared.com <msdn@comsquared.com> said:
[quoted text, click to view] > [...]
> Given:
> Thread B performs: lock(x) { ... Monitor.Wait(x) ... }
>
> Thread A performs: while(1) { lock(x) { ... Monitor.Pulse(x) ... } }
>
> Thread B will be starved out waiting for the mutex on x and there is no
> sequencing guarantee that thread B will finish executing before thread A
> reaquires the mutex. Is this a bug or intended behavior?
I don't know enough about the Monitor class to answer the specific
question. However, assuming it works in conjunction with the usual
thread synchronization and scheduling mechanisms, then I would expect
thread A to continue running until it explicitly blocks or exhausts its
timeslice. So thread B won't get to acquire the lock until that point.
If thread A still has the lock when its timeslice runs out, thread B
still won't be able to acquire the lock.
The docs might not be very clear on that, but it does seem to me to be
a reasonable expectation based on how the rest of Windows works.
Assuming the other threads are all of the same priority as thread A,
then calling Sleep(0) in thread A after releasing the lock should allow
other threads to get their chance at it. If those other threads are of
lower priority, then calling Sleep(1) would be necessary.
I can't say for sure what Microsoft would say, but assuming the intent
is for Monitor to be reasonably lightweight, I would call this
"intended behavior". The alternative is for Monitor to have to do
extra work to decide what happens when a lock is released or acquired
and/or always yield to other threads when releasing a lock, either of
which could impair performance when not needed.
Pete