为什么Boost scoped_lock没有解锁互斥锁?

时间:2009-08-10 17:46:04

标签: c++ multithreading boost mutex

我一直以这种方式使用boost::mutex::scoped_lock

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
}

基本上它设置了waitBoolean,而另一个线程通过将waitBoolean设置为false来表示它已完成;

但这似乎不起作用,因为其他线程无法锁定mutex_ !!

我假设通过将scoped_lock包装在括号中,我将终止其锁定。情况并非如此?在线阅读说它只在调用析构函数时放弃互斥锁。当它超出当地范围时不会被销毁吗?

信令部分代码:

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

谢谢!

3 个答案:

答案 0 :(得分:22)

要同步两个线程,请使用条件变量。这是以您希望的方式同步两个线程的最先进方式:

使用boost,等待部分类似于:

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

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

通知部分类似于:

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

    _condition.notify_all();
}

使用_synchronisationSent的业务是为了避免激烈的唤醒:见wikipedia

答案 1 :(得分:16)

确实应该在范围的末尾发布scoped_lock。但是当你在它上面循环时你不会锁定waitBoolean,这表明你也没有在其他地方正确地保护它 - 例如它被设置为假,你最终会遇到令人讨厌的竞争条件。

我会说你应该使用boost :: condition_variable来做这类事情,而不是睡眠+线程不安全的检查。

答案 2 :(得分:0)

另外我建议将waitBoolean标记为volatile,但是你必须使用条件或更好的屏障。