Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-08-13 14:36:30


From: "Alexander Terekhov" <terekhov_at_[hidden]>

> > Yep, one queue per thread. Just like the original example - one CV per
> > thread - unless I misinterpreted it.
>
> how about one mutex/CV *per queue* with multiple threads..

What is the scenario? I can see the code and I think I understand it, but
what is it supposed to do, and is this a common example? One thing that's
not apparent from the code is whether notifyThread() is supposed to be
"thread-safe" as well, i.e. are multiple threads allowed to concurrently
call notifyThread.

> mutex m;
> queue<int> q;
> condition cv;
>
> void threadfunc()
> {
> for(;;)
> {
> int m;
> {
> mutex::scoped_lock lock( m );
> while(q.empty())
> cv.wait( lock );
> m = q.pop();
> }
> 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)
> {
> {
> mutex::scoped_lock lock( m );
> q.push(a + 2 * b + 4 * c);
> }
> cv.notify_one();
> }

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();
}

Or something like that. Of course fully_synchronized_queue has a hidden
mutex and every push/pop acquires a hidden lock; the point is that the user
doesn't see the complexity. Simpler is usually better - unless it's
incorrect, of course. :-)

It's possible to move the wakeup event into the queue as well; likeiwse, in
the cv-based example, we can move the mutex and the cv into the queue:

void threadfunc()
{
  for(;;)
  {
    int m;

    while(q.pop(m)) // blocks
    {
      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);
}

But this doesn't handle termination.

--
Peter Dimov
Multi Media Ltd.

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