13

私は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;
   }
}

ありがとう!

4

3 に答える 3

22

2 つのスレッドを同期するには、条件変数を使用します。これは、必要な方法で 2 つのスレッドを同期する最先端の方法です。

ブーストを使用すると、待機部分は次のようになります。

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 のビジネスは、誤ったウェイクアップを回避することです:ウィキペディアを参照してください

于 2009-08-10T18:02:32.890 に答える
16

scoped_lockは、実際にスコープの最後で解放する必要があります。ただし、ループしているときにwaitBooleanをロックしないでください。これは、他の場所(たとえば、falseに設定されている場所)でも、waitBooleanを適切に保護しないことを示唆しており、厄介な競合状態になります。

この種のことを行うには、sleep +スレッドセーフチェックの代わりに、boost::condition_variableを使用する必要があると思います。

于 2009-08-10T17:54:23.513 に答える
0

また、waitBoolean を volatile としてマークすることをお勧めしますが、条件を使用するか、バリアを使用する必要があります。

于 2012-08-31T15:14:04.400 に答える