views:

2896

answers:

2

I've been using boost::mutex::scoped_lock in this manner:

void ClassName::FunctionName()
{
    {  
     boost::mutex::scoped_lock scopedLock(mutex_);
     //do stuff
      waitBoolean=true;
    }
    while(waitBoolean == true ){
        sleep(1);
    }
    //get on with the thread's activities
}

Basically it sets waitBoolean, and the other thread signals that it is done by setting waitBoolean to false;

This doesn't seem to work, however, because the other thread can't get a lock on mutex_ !!

I was assuming that by wrapping the scoped_lock in brackets I would be terminating its lock. This isn't the case? Reading online says that it only gives up the mutex when the destructor is called. Won't it be destroyed when it goes out of that local scope?

Signaling part of code:

while(running_){
   boost::mutex::scoped_lock scopedLock(mutex_);
   //Run some function that need to be done...
   if(waitBoolean){
      waitBoolean=false;
   }
}

Thanks!

+6  A: 

The scoped_lock should indeed be released at the end of the scope. However you don't lock the waitBoolean when you're looping on it, suggesting you don't protect it properly other places as well - e.g. where it's set to false, and you'll end up with nasty race conditions.

I'd say you should use a boost::condition_variable to do this sort of things, instead of sleep + thread-unsafe checking.

nos
+9  A: 

To synchronize two threads use a condition variable. That is the state of the art way to synchronize two threads the way you want :

Using boost, the waiting part is something like :

void BoostTimedSynchronisationPoint::waitSynchronisation()
{
    boost::unique_lock<boost::mutex> lock(_mutex);

    while(!_synchronisationSent)
    {
        _condition.wait(lock); // unlock and wait
    }

    _synchronisationSent = false;
}

The notify part is something like :

void BoostTimedSynchronisationPoint::sendSynchronisation()
{
    {
        boost::lock_guard<boost::mutex> lock(_mutex);
        _synchronisationSent = true;
    }

    _condition.notify_all();
}

The business with _synchronisationSent is to avoid spurrious wakeups : see wikipedia

neuro