技術的な理由はありませんか?
彼が技術的な理由を与えたと私は信じているので、私は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();
}
これはまさに、を使用すべきではないcondition_variable方法です。でマークされた地域:
// mut locked by this thread here
例外安全性の問題があり、それは深刻な問題です。これらの領域で(または単独で)例外がスローされた場合、例外cv.waitをキャッチしてロックを解除するためにtry / catchもどこかに配置されない限り、ミューテックスのロック状態がリークされます。しかし、それはあなたがプログラマーに書くように頼んでいる単なるより多くのコードです。
プログラマーが例外安全なコードを書く方法を知っていて、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誤ってミューテックスを参照しない場合、nullポインタの逆参照が発生する可能性があります。condition_variable::waitそして、このスレッドがのロックを所有していることを確認する方法はありませんmut。
ああ、覚えておいてください、プログラマーがunique_lockミューテックスを公開するために間違ったメンバー関数を選択するかもしれないという危険もあります。 *lk.release()ここでは悲惨なことになります。
次に、 :を使用する実際のcondition_variableAPIを使用してコードがどのように記述されているかを見てみましょう。unique_lock<mutex>
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。
さらに、あなたが言うように理由はcondition_variable::waitありません:私は破壊されるまでこのミューテックスのロックを所有しています。ただし、を呼び出すと、ミューテックスのロックが暗黙的に解放されます。そのため、アクションはユースケース/ステートメントと矛盾します。lock_guard<mutex>lock_guard<mutex>lock_guard<mutex>condition_variable::waitlock_guard
unique_lockとにかく、関数からロックを返し、それらをコンテナーに入れ、例外安全な方法でスコープ外のパターンでミューテックスをロック/ロック解除できるようにする必要があったので、unique_lockの自然な選択でしたcondition_variable::wait。
アップデート
バンボンは私が対照的であると以下のコメントで提案したcondition_variable_anyので、ここに行きます:
質問:任意のタイプをcondition_variable::wait渡すことができるようにテンプレート化されて いないのはなぜですか?Lockable
答え:
それは本当に素晴らしい機能です。たとえば、このペーパーshared_lockでは、条件変数(posixの世界では前例のないものですが、それでも非常に便利です)で共有モードの(rwlock)を待機するコードを示します。ただし、機能はより高価です。
そこで、委員会はこの機能を備えた新しいタイプを導入しました。
`condition_variable_any`
このcondition_variable アダプタを使用すると、ロック可能なタイプを待つことができます。メンバーがいる場合はlock()、unlock()行ってもいいです。の適切な実装にcondition_variable_anyは、condition_variableデータメンバーとデータメンバーが必要shared_ptr<mutex>です。
Because this new functionality is more expensive than your basic condition_variable::wait, and because condition_variable is such a low level tool, this very useful but more expensive functionality was put into a separate class so that you only pay for it if you use it.