2009-08-10 50 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奧利安,但是你必須使用一個條件或甚至更好的屏障。