1

このコードは、プロデューサーの内部のミューテックスを待機することはありvoid push(data)ますか?

もしそうなら、どうすればそれを回避できますか?

boost::mutex access;
boost::condition cond;

// consumer
data read()
{
  boost::mutex::scoped_lock lock(access);

  // this blocks until the data is ready
  cond.wait(lock);

  // queue is ready
  return data_from_queue();
}

// producer
void push(data)
{
  //<--- will a block ever happen here?
  boost::mutex::scoped_lock lock(access);
  // add data to queue

  cond.notify_one();  
}

for(;;) ループのスレッド プールがあり、このプール内のスレッドから read() が呼び出されているとします。次に、その上でデータを処理します。そして、いくつかの外部スレッドで push() を呼び出します。私の質問は、その外部スレッドが push(data) への呼び出しでブロックされることはありますか?

4

2 に答える 2

8

waitnotify呼び出されることなく戻ることができます。これは、スプリアスウェイクアップと呼ばれます。waitこれを処理するには、条件を使用するコードに、期待される条件が実際に有効であることを確認するループが常に含まれている必要があります。例えば:

queue data_queue;
boost::mutex access;
boost::condition cond;

// consumer
data read()
{
  boost::mutex::scoped_lock lock(access);

  while (queue.is_empty()) {
    // this blocks until the data is ready
    cond.wait(lock);
  }

  // queue is ready
  return data_from_queue();
}

// producer
void push(data)
{
  boost::mutex::scoped_lock lock(access);

  // add data to queue
  queue.push_back(data);

  cond.notify_one();  
}

概念的には、「状態」は一種の誤解を招くものです。代わりに、それを信号と考えることができます。別のスレッドにウェイクアップするように通知していますが、何も約束していません。ただ、「ねえ、データの準備ができているかもしれない。チェックしてみませんか?」

于 2009-06-23T17:36:09.913 に答える
0

.wait() が呼び出されると、スレッド プール内の呼び出し元のスレッドがブロックされ、ミューテックスが解放されます。誰かが notify_one() または notify_all() を呼び出すと返されます。ただし、ブロックされたスレッドが戻る前に、ミューテックスを再取得し、スレッド プール内のスレッドのブロックを解除します。

したがって、void push(data)外部スレッドによる への呼び出しは、.wait() が呼び出されるまで一時的にのみブロックされます。

条件の待機機能に関するブーストのドキュメントを参照してください。

于 2009-06-23T18:11:19.613 に答える