1
boost::condition cond;
boost::mutex access;
void listener_thread()
{
  boost::mutex::scoped_lock lock(access);

  while (true) {
      while (!condition_check_var) {
          cond.wait(lock);
      }
      do_some_work();
  }
}

/// ... Main thread ...
cond.notify_all();
check_work:
{
    boost::mutex::scoped_lock lock(access);
    function_relies_on_work_been_done();
}

これは適切な設計ですか?notify_all()が返されたら、listener_thread はすでにロックを取得していると想定しても安全ですか? そして、check_workブロックが実行されるとき (それは と同じミューテックスをロックしているので)、いくつかの「作業」は?listener_thread()によってすでに行われているでしょう。listener_thread()

そうでない場合、この種の動作を実現するための好ましい方法は何ですか?

4

2 に答える 2

3

他のスレッドが通知に基づいて動作した、またはまだ受信しているという保証はありません。実際、現在受信を待機しているスレッドがあるという保証さえありませんが、セットアップでは、待機しているスレッドが存在する可能性が高いように見えます。受信スレッドが作業を完了したことを確認したい場合は、たとえば、別の条件変数と適切な条件を使用して、リバース コミュニケーション チャネルを設定する必要があります。

あなたの質問はBoostに関するものだと思いますが、これについて標準が言わなければならないことは次のとおりです(30.5.1 [thread.condition.condvar]段落8):

void notify_all() noexcept; 効果: を待ってブロックされているすべてのスレッドのブロックを解除し*thisます。

スレッドや関連するミューテックスに何が起こるかについては保証されません。

于 2012-11-25T23:57:17.717 に答える
1

一般的には問題ありませんが、典型的な書き方は次のようになります。

while (true)
{
    cond.wait(lock, [&]() -> bool { return condition_check_var; });
    do_some_work();
}

notify_all()呼び出しと の戻りの同時性について話すことはできませんwait()。この 2 つの間に正式な因果関係がないためです。同期について知っておく必要があるのは、wait()戻ったときにロックを取得しているということだけです。check_workブロックもミューテックスをロックするため、他のスレッドが条件変数でブロックしている間のみ実行されることが保証されます。

于 2012-11-25T23:50:05.067 に答える