2009-08-10 74 views
12

私は、このようにboost::mutex::scoped_lockを使用してきた:Boost scoped_lockがmutexのロックを解除しないのはなぜですか?

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を設定し、これをfalseにwaitBooleanを設定することによって行われている他のスレッドシグナル;

しかし、他のスレッドがmutex_でロックを取得できないため、これは機能していないようです。

私はscoped_lockを角かっこで囲むことでロックを終了すると仮定していました。これはそうではありませんか?オンラインを読むと、デストラクタが呼び出されるときにだけmutexを放棄すると言われています。その地方の範囲から外れると、それは破壊されませんか?コードの一部をシグナリング

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

ありがとう!

+1

scoped_lockオブジェクトは閉じ括弧で破棄され、mutexは解放されます。コードのシグナル部分を投稿してください。 ところで、boost :: condition_variableはあなたのニーズに合っています – neuro

+0

あなたのシグナリングコードを見ると、ある場合には動作しますが、あなたの処理(あなたのコメント)によって異なります。他のシンクロがあればそれは悪化する。条件変数はそれを行う方法です。この種のシンクロをするために使用するコードを投稿しました。 – neuro

+0

シグナルスレッドの「仕事」は他のものをロックしません。それは独立して実行されます。 – Alex

答えて

16

scoped_lockは実際にスコープの終わりにリリースされるべきです。ただし、ループしているときにwaitBooleanをロックしないでください。他の場所でも適切に保護しないことをお勧めします。どこが偽に設定されているのか、あなたは厄介な競争条件に終わるでしょう。

私はsleep :: thread-unsafeチェックではなく、このようなことをするためにboost :: condition_variableを使うべきでしょう。

22

2つのスレッドを同期させるには、条件変数を使用します。それは二つのスレッドあなたが望むように同期させるための芸術の道の様子です:

ブーストを使用して、待機中の一部のようなものです:

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

    _condition.notify_all(); 
} 

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

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

ザ・パートのようなもので知らせます

_synchronisationSentのビジネスは、多忙な起床を避けることです:

0

また私は、しかし、あなたは条件を使うか、より良い障壁を使う必要があります。

関連する問題