1

タスクを非同期的に処理する「エンジン」があり、1つのタスクについて、そのタスクが処理されるまで待機したいと思います。

boost::condition_variable cvWorkDone;

DoSomeWork()
{
   PostAsyncJob(DoWorkAsync)   // is a boost::asio::post

   boost::mutex::scoped_lock lock(mtxWorkDoneCv);
   cvWorkDone.wait(lock);
}


DoWorkAsync()
{
   // do some work ...

   cvWorkDone.notify_one();
}

問題は、上記のコードに競合状態があることです。前にそれを待つようにDoWorkAsync()通知した場合はどうなりますか?boost::condition_variableDoSomeWork()

boost::condition_variable::waitこれには2番目のパラメーター、このようなものを実装するために使用できるブール値があることがわかります

bool bWait;

DoSomeWork()
{
   bWait = true;
   PostAsyncJob(DoWorkAsync)   // boost::asio::post

   boost::mutex::scoped_lock lock(mtxWorkDoneCv);
   cvWorkDone.wait(lock, bWait);
}


DoWorkAsync()
{
   // do some work ...
   boost::mutex::scoped_lock lock(mtxWorkDoneCv);
   cvWorkDone.notify_one();      
   bWait = false;
}

しかし、並行性はまだあります...どうすればこれを解決できますか?

4

1 に答える 1

3

条件変数は、シグナルが送信されたかどうかについての状態を維持しないため、条件変数が個別にシグナルを送信される理由が何であれ、状態を維持する必要があります (場合によっては、キューなどの理由シグナルされる条件変数は、非同期的に消える可能性があります)。したがって、コードに次のようなものがあるかもしれません:

boost::condition_variable cvWorkDone;
bool workdone = false;

DoSomeWork()
{
   PostAsyncJob(DoWorkAsync)   // is a boost::asio::post

   boost::mutex::scoped_lock lock(mtxWorkDoneCv);
   while (!workdone) {
      cvWorkDone.wait(lock);
   }
}


DoWorkAsync()
{
   // do some work ...

   {   
      boost::mutex::scoped_lock lock(mtxWorkDoneCv);
      workdone = true;
   }
   cvWorkDone.notify_one();
}

これにより、 からのスプリアス リターンも保護されることに注意してくださいboost::condition_variable::wait()。上のブーストドキュメントからboost::condition_variable::wait()

スレッドは、this->notify_one() または this->notify_all() への呼び出しによって通知されるか、偽装してブロックを解除します。

于 2012-10-15T14:38:54.260 に答える