2009-08-10 51 views
12

我以这种方式使用boost::mutex::scoped_lock为什么Boost 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做其他线程的信号;

但是,这似乎不起作用,因为其他线程无法获得互斥体锁!

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

信令部分:

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

谢谢!

+1

scoped_lock对象在您的右括号中被销毁并释放互斥锁。请发布代码的信号部分。 顺便提一下,boost :: condition_variable更适合您的需求 – neuro 2009-08-10 17:55:25

+0

看到您的信令代码它可以在某些情况下工作,但取决于您所做的处理(您的意见)。如果有其他同步器,则会更糟糕。条件变量是实现这一目标的方法。我发布了用于执行此类同步的代码。 – neuro 2009-08-10 18:19:19

+0

信号线程的“工作”不会锁定其他任何东西。它独立运行。 – Alex 2009-08-10 18:27:08

回答

16

scoped_lock的确应该在范围的末尾释放。但是,当您循环时,您不会锁定waitBoolean,这表明您不会在其他位置正确保护它 - 例如,它被设置为false,并且最终会遇到令人讨厌的竞争条件。

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

22

要同步两个线程,请使用条件变量。这就是艺术的方法来同步两个线程你想要的方式状态:

使用升压时,等待的部分是这样的:

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

0

另外,我会建议标记为volatile,waitBo奥利安,但是你必须使用一个条件或甚至更好的屏障。