2

次のブログ投稿:

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

次のように定義された「プッシュ」メソッドがあります。

void push(Data const& data)
{
   boost::mutex::scoped_lock lock(the_mutex);
   the_queue.push(data);
   lock.unlock();
   the_condition_variable.notify_one();
}

私の質問は次のとおりです。

  1. scoped_lock変数に対して明示的な「lock.unlock()」が呼び出されるのはなぜですか?

  2. その目的は何ですか?

  3. 安全に削除して、'notify_one'メソッド呼び出しをscoped_mutexのスコープ内に収めることができますか?

4

3 に答える 3

6

ロック解除は必要ありません。ただし、ミューテックスがわずかにロックされる時間を短縮できる場合があります。

それを保持または削除しても、スレッドの安全性に影響を与えたり、デッドロックが発生したりすることはありません。

編集:ただし、記事に記載されているように、ロックを解除したままにしておくと、ミューテックスでの競合が少なくなる可能性があります。または、ミューテックスの周囲のスコープを使用することもできます。これは、コードを一瞥すると、ミューテックスのスコープをよりよく強調していると私は個人的に感じています。

于 2012-05-22T08:05:14.913 に答える
3

明示的なロックは、待機中のスレッドが通知によって起こされないようにするためのもので、ミューテックスでブロックする必要があるだけです。これは、リンクした記事の前半で説明されています。

引き続きaを使用する理由scoped_lockは、プッシュが失敗して例外がスローされた場合にミューテックスが適切にロック解除されていることを確認するためです。

于 2012-05-22T08:08:44.353 に答える
3

ポイント1と2は、ロックをできるだけ短時間保持する必要があるという原則によって答えることができます。データがキューにプッシュされるとすぐに、データをロックする必要がなくなります。

あなたが提案したように、ロックを解除することができますが、ロックをより長く維持することを犠牲にします。

または、次のように新しいスコープを追加することで、ロック解除自体を削除できます。

void push(Data const& data)
{
   { // new scope
      boost::mutex::scoped_lock lock(the_mutex);
      the_queue.push(data);
   } // scope ends, lock gets destroyed
   the_condition_variable.notify_one();
}
于 2012-05-22T08:09:39.223 に答える