the wait() and pulse() of monitor

  • Thread starter Thread starter pt
  • Start date Start date
P

pt

hello, all

I am puzzled by monitor.wait() and monitor.pulse().
Currently, my understanding is if a thread calls wait(), it must
be pulsed first before it can wake up. What is the benifit
to realize the syschronization as so? In my inpression, no
other synchronization mechanism like it.why not simply use wait()
and let the wait() can wakeup without being pulsed()? I know the
pulse() introduces more control, but is there some example show the
benefit of pulse() ?


Also, I know the difference of pulse() and pulseall(), but I
think in most case pulseall() is enough I would like to know
in which case pulse() should be used as necessary?

many thanks!
 
pt said:
I am puzzled by monitor.wait() and monitor.pulse().
Currently, my understanding is if a thread calls wait(), it must
be pulsed first before it can wake up. What is the benifit
to realize the syschronization as so? In my inpression, no
other synchronization mechanism like it.

On the contrary, it's quite common.
why not simply use wait()
and let the wait() can wakeup without being pulsed()?

That sounds like Thread.Sleep to me.
I know the
pulse() introduces more control, but is there some example show the
benefit of pulse() ?

A good example is a producer/consumer scenario: you have a worker
thread waiting for jobs, and another thread which produces jobs to be
done. When the queue of jobs is empty, the worker thread waits on a
monitor, and when the producer adds a job to the queue, it pulses the
monitor to wake up the worker thread.
Also, I know the difference of pulse() and pulseall(), but I
think in most case pulseall() is enough I would like to know
in which case pulse() should be used as necessary?

Pulse is used instead of PulseAll when there may be multiple threads
waiting on the same monitor, but the thread doing the pulsing knows
that only one of them can usefully do work due to its pulse.
 
Jon Skeet said:
On the contrary, it's quite common.


That sounds like Thread.Sleep to me.


A good example is a producer/consumer scenario: you have a worker
thread waiting for jobs, and another thread which produces jobs to be
done. When the queue of jobs is empty, the worker thread waits on a
monitor, and when the producer adds a job to the queue, it pulses the
monitor to wake up the worker thread.

but the pulse() just mean that the producer is ready to free the control
and the producer still should use the wait() or exit() to free the lock and
then the worker can get the lock.
So there is three state for the worker

wait--pulsed(don't get the lock and still can do nothing)--get lock and work

I just wonder why introduced the middle state--pulsed? I still think
in this case it is not necessary.
Pulse is used instead of PulseAll when there may be multiple threads
waiting on the same monitor, but the thread doing the pulsing knows
that only one of them can usefully do work due to its pulse.

but in the pulse() function, no distinct thread can be designated. So
the case maybe each one thead's state is the same and only need one
of them to wake up?

regards,
PanTao
 
pt said:
but the pulse() just mean that the producer is ready to free the control
and the producer still should use the wait() or exit() to free the lock and
then the worker can get the lock.

No, the producer doesn't use wait itself at all. The sequence is:

Consumer: Producer:
Enter lock
Wait (exits lock)
Enter lock
Pulse
Exit lock
Regain lock
Exit lock

The lock isn't held by anyone for long.
So there is three state for the worker

wait--pulsed(don't get the lock and still can do nothing)--get lock and work

I just wonder why introduced the middle state--pulsed? I still think
in this case it is not necessary.

I think you're missing something, but it's hard to say what it is, I'm
afraid.
but in the pulse() function, no distinct thread can be designated. So
the case maybe each one thead's state is the same and only need one
of them to wake up?

Yes. If it matters which one is woken, you either need different
monitors for the different types of event, or use PulseAll.
 
"Jon Skeet [C# MVP]" <[email protected]> ????
....
No, the producer doesn't use wait itself at all. The sequence is:

Consumer: Producer:
Enter lock
Wait (exits lock)
Enter lock
Pulse
Exit lock
Regain lock
Exit lock

It is just for one time operation. If producer produces more , then
there will a loop in the block and in the loop pulse and wait will
be used.
The lock isn't held by anyone for long.


I think you're missing something, but it's hard to say what it is, I'm
afraid.

the explain for pulse is so in msdn:
Sends a signal to one or more waiting threads. The signal notifies a waiting
thread that the state of the locked object has changed, and the owner of the
lock is ready to release the lock. The waiting thread is placed in the
object's ready queue so that it might eventually receive the lock for the
object.Once the thread has the lock, it can check the new state of the
object
to see if the required state has been reached.

I think once wait() is called, the thread fall into a state wait and can't
join the competion for the lock unless being pulsed first.

so totally I think there are three state:

gain lock, wait and have not been pulsed, waitlock(means just waiting the
lock,while first enter() or have been pulsed).and pulse() can let thread
change from wait to waitlock.

I think the wait state introduce more control function, but I would like to
see which case it should be used. I think it will used while there is more
threads and the control is complex, but I can't imagine the detail case.

regards,
PanTao
 
pt said:
It is just for one time operation. If producer produces more , then
there will a loop in the block and in the loop pulse and wait will
be used.

No, the producer would just pulse multiple times. Why would the
producer wait? The idea of this is that the producer is just using
"fire and forget" semantics.
the explain for pulse is so in msdn:
Sends a signal to one or more waiting threads. The signal notifies a waiting
thread that the state of the locked object has changed, and the owner of the
lock is ready to release the lock. The waiting thread is placed in the
object's ready queue so that it might eventually receive the lock for the
object.Once the thread has the lock, it can check the new state of the
object to see if the required state has been reached.

I think once wait() is called, the thread fall into a state wait and can't
join the competion for the lock unless being pulsed first.

Yes. (Assuming a timeout isn't specified.)
so totally I think there are three state:

gain lock, wait and have not been pulsed, waitlock(means just waiting the
lock,while first enter() or have been pulsed).and pulse() can let thread
change from wait to waitlock.

Um, I think so.
I think the wait state introduce more control function, but I would like to
see which case it should be used. I think it will used while there is more
threads and the control is complex, but I can't imagine the detail case.

I've shown you a case where it's used - the classic producer/consumer
situation, with a queue of jobs. Please explain how you would tackle
that without wait/pulse (or any similar but equivalent mechanism).
 
I've shown you a case where it's used - the classic producer/consumer
situation, with a queue of jobs. Please explain how you would tackle
that without wait/pulse (or any similar but equivalent mechanism).

I just think in the producer/consumer case, the complex corporation
that pulse() and wait() is not used, since in the case, the state(
waited but haved not been pulsed) for consumer has no special effect,
and the state is no necessary in the case. and the producer has
to use two step pulse() and exit() or wait to do the work, and
with other machanism such as samaphore, just one step does the work.

regards,
 
pt said:
I just think in the producer/consumer case, the complex corporation
that pulse() and wait() is not used, since in the case, the state(
waited but haved not been pulsed) for consumer has no special effect,
and the state is no necessary in the case.

How exactly do you make the consumer wait until the producer has
produced something and reliably then consume it?
and the producer has
to use two step pulse() and exit() or wait to do the work, and
with other machanism such as samaphore, just one step does the work.

No, the producer can't hold the lock the whole time and just release it
to effectively pulse the consumer, for two reasons:

1) There may well be more than one producer
2) There's no guarantee that *as soon as* the producer releases the
lock, the consumer will get it. If the producer is then going to
acquire the lock again, that may happen before the consumer acquires
it.

Nothing should hold locks for long periods of time, in my view, but I
*think* that's what you're proposing.
 
Back
Top