std::condition_variable
明らかな何かが欠けている可能性がありますが、との違いはわかりませんstd::condition_variable_any
。なぜ両方が必要なのですか?
2 に答える
違いは、wait()
関数へのパラメーターです。のすべての待機関数std::condition_variable
は type のロック パラメーターを受け取りますがstd::unique_lock<std::mutex>&
、 の待機関数std::condition_variable_any
はすべてテンプレートであり、 type のロック パラメーターを受け取ります。Lockable&
ここLockable
で、 はテンプレート パラメーターです。
これは、std::condition_variable_any
がユーザー定義のミューテックスとロックの種類、およびboost::shared_lock
---lock()
とunlock()
メンバー関数を持つすべてのもので動作できることを意味します。
例えば
std::condition_variable_any cond;
boost::shared_mutex m;
void foo() {
boost::shared_lock<boost::shared_mutex> lk(m);
while(!some_condition()) {
cond.wait(lk);
}
}
C++20 以降condition_variable_any
、新しい jthread クラスのストップ トークンもサポートします。これは、このタイプの条件変数がある場合、停止要求が行われるとミューテックスを放棄することを意味し、追加のポーリング コードを記述する必要はありません。condition_variable
この機能は、「競合、デッドロック、および未定義の動作」を引き起こしている技術的な理由により機能しません。
void testInterruptibleCVWait()
{
bool ready = false;
std::mutex readyMutex;
std::condition_variable_any readyCV;
std::jthread t([&ready, &readyMutex, &readyCV] (std::stop_token st)
{
while (...)
{
...
{
std::unique_lock lg{readyMutex};
readyCV.wait_until(lg, [&ready] {return ready; }, st);
// also ends wait on stop request for st
}
...
}
});
...
} // jthread destructor signals stop request and therefore unblocks the CV wait and ends the started thread
詳細については、ドキュメントを参照してください。
std::condition_variable
ドキュメンテーション
std::condition_variable_any
ドキュメントを参照し、特にjthread で停止要求を受け入れるようになったwait
、wait_for
およびメンバー関数を調べます。wait_until
または、最新の jthread と停止トークン C++20 提案リビジョンをチェックしてください
std::condition_variable
はより特化されているため、 の柔軟性が必要ない場合はより効率的ですstd::condition_variable_any
。
N3290 §30.5[thread.condition]/1 から
Class
condition_variable
は、 type のオブジェクトでのみ待機できる条件変数を提供し、unique_lock<mutex>
一部のプラットフォームで最大の効率を実現します。クラスcondition_variable_any
は、ユーザー指定のロック タイプのオブジェクトを待機できる一般的な条件変数を提供します。
実際、LLVM の libc++ では、shared_mutex でcondition_variable_any
より特殊化された (pthread_cond_t を使用する) を使用して実装されています。condition_variable