Boost logo

Boost :

From: Alexander Terekhov (terekhov_at_[hidden])
Date: 2001-08-13 16:15:41


> fully_synchronized_queue<int> q;
> auto_reset_event wakeup;
> manual_reset_event terminate;
>
> void threadfunc()
> {
> for(;;)
> {
> if(waitFor(wakeup, terminate) == 1) break;
>
> int m;
>
> while(q.pop(m))
> {
> if(m & 1) do_something_a();
> if(m & 2) do_something_b();
> if(m & 4) do_something_c();
> }
> }
> }
>
> void notifyThread(bool a, bool b, bool c)
> {
> q.push(a + 2 * b + 4 * c);
> wakeup.raise();
> }

another problem you have with the code above
is the following.. suppose you have N worker
threads active in q.pop loop crunching fairly
big queue.. at some point in time they will
run out of work and will try to wait for more
work via waiting on wakeup event. but they
could become preempted on their way to
waitFor(wakeup) in favor of one or more producer
threads which could fill the queue again. now..
when the first/fastest worker thread would call
waitFor(wakeup).. it will consume the auto-reset
event (signaled multiple times) which could result
in all other worker threads remained blocked on
wakeup event even with queue full of work which
is supposed to keep multiple worker threads busy;
not blocked! full (non-binary) semaphore would solve
this problem of lost wakeups but that would introduce
another mutex (inside semaphore) and another counter
(again inside semaphore) and that is in addition to
mutex already used to protect the queue including
its internal "counter", etc..

with CV based solution you simply do not have all
these problems/inefficiencies.

regards,
alexander.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk