ので、技術的な理由はありませんか?
私は彼が技術的理由を与えたと信じているので、cmeerwの答えをアップアップしました。それを歩みましょう。委員会がcondition_variable
をmutex
に待つことを決めたとしよう。ここでのコードは、そのデザインを使用している:
void foo()
{
mut.lock();
// mut locked by this thread here
while (not_ready)
cv.wait(mut);
// mut locked by this thread here
mut.unlock();
}
これは、1つのがcondition_variable
を使うべきではありません正確にどのようにあります。
// mut locked by this thread here
の領域では、例外的な安全上の問題があり、深刻な問題です。これらの領域(またはcv.wait
自身)によって例外がスローされた場合、try/catchも例外を捕捉してロックを解除しない限り、mutexのロック状態がリークします。しかし、これはプログラマに書かせてほしいコードです。
プログラマが例外セーフコードを書く方法を知っていて、それを達成するためにunique_lock
を使用することがわかっているとします。コードは次のようになります。
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(*lk.mutex());
// mut locked by this thread here
}
これははるかに優れていますが、まだまだ大きな状況ではありません。 condition_variable
インターフェイスは、プログラマーが自分の道を離れて仕事をするようにしています。 lk
が誤ってミューテックスを参照していない場合、ヌルポインタ逆参照が発生する可能性があります。そして、condition_variable::wait
がこのスレッドがmut
にロックを所有していることを確認する方法はありません。
ああ、ちょっと思い出して、プログラマが誤ってunique_lock
メンバ関数を選択してミューテックスを公開する危険もあります。 はここで悲惨です。
今度は、コードがunique_lock<mutex>
をとり、実際のcondition_variable
APIで書かれている方法を見てみましょう:
void foo()
{
unique_lock<mutex> lk(mut);
// mut locked by this thread here
while (not_ready)
cv.wait(lk);
// mut locked by this thread here
}
- このコードは、それが得ることができるのと同じくらい簡単です。
- 例外的に安全です。
wait
関数はlk.owns_lock()
をチェックし、false
の場合は例外をスローすることができます。
これは、APIデザインcondition_variable
の技術的な理由によるものです。私はlock_guard<mutex>
破棄されるまで、このミューテックスのロックを所有して:lock_guard<mutex>
は、あなたが言うかあるので
さらに、condition_variable::wait
はlock_guard<mutex>
を負いません。しかし、condition_variable::wait
に電話すると、暗黙的にmutexのロックが解除されます。したがって、そのアクションはlock_guard
ユースケース/ステートメントと矛盾します。
1は、容器に入れて、関数からロックを返すことができるように私たちは、とにかくunique_lock
を必要に応じて、ロック/は例外安全な方法で非スコープのパターンでミューテックスのロックを解除するので、unique_lock
はcondition_variable::wait
のための自然な選択でした。
更新
bamboonはそうここに、そのIコントラストcondition_variable_any
以下のコメントで示唆:
質問:私はそれにあらゆるLockable
型を渡すことができるようにテンプレートではないcondition_variable::wait
れるのはなぜ ?
回答:
持っている本当にクールな機能です。たとえば、this paperは、条件変数(posix世界では聞こえていないものの、それでもなお非常に便利です)で共有モードでshared_lock
(rwlock)を待つコードを示しています。しかし、その機能はより高価です。 あらゆるロック可能なタイプに待つことができます。このcondition_variable
アダプタ 1で
`condition_variable_any`
:
だから委員会は、この機能を持つ新しいタイプを導入しました。メンバーに
lock()
と
unlock()
がある場合、あなたはいいです。
condition_variable_any
を適切に実装するには、データメンバー
condition_variable
とデータメンバー
shared_ptr<mutex>
が必要です。
この新しい機能は基本的なcondition_variable::wait
よりも高価であり、condition_variable
はそのような低レベルのツールなので、この非常に便利だが高価な機能は別のクラスに入れられているため、 。
条件変数でロック/ミューテックスが必要な理由、またはロックとミューテックスの違い、または条件変数がミューテックスではなくユニークなロックを使用する理由について混乱していますか? – Brady
"なぜ条件変数はmutexではなく一意のロックを使用するのですか?" –