Boost logo

Boost Users :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2005-08-11 03:33:01


Christian Henning wrote:

> Hi Ben,
> The boost::thread::join() is only for waiting for a thread to
> complete. I don't want to complete the thread when calling stop(). I
> just want to put it into the blocked state.
>
> I run into a deadlock when I finish the app. I call the stop() and
> then the ~fvAsynchronousSequencer. But usually the thread isn't
> stopped when entering the destructor and when the thread stops after I
> called notify_one() I'm inside a deadlock.

Looks like you've missed what Ben said -- you should never, ever use
condition variable in the way you do:

   {
      boost::mutex::scoped_lock oLock( _oTerminateMutex );
      _oTerminateCond.wait( oLock );
   }

This is asking for troubles -- you can miss "notify_one" if it's executed
before you call "wait", and you get awake when nobody called "notify_one".

Some more details can be found in:

   http://vladimir_prus.blogspot.com/2005/07/spurious-wakeups.html

and any book on threading says the same.

> So, is there a way, that when the stop() returns, the worker thread is
> blocked?

Sure:

   enum Worker_status { running = 1, stopped } status;

   void stop()
   {
        boost::mutex::scoped_lock l(m);
        _bStop = true;
        while(status != stopped)
        {
                cond.wait(l);
        }
        _bStop = false;
   }

   void runner()
   {
        for(;;)
        {
                // so some work.
                if (_bStop)
                {
                        boost::mutex::scope_lock l(m);
                        status = stopped;
                        cond.notify_all();
                }
        }
   }

or something like that. I haven't seen your header -- but making _bStop
volatile will not hurt too.

- Volodya


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net