25

std::condition_variable明らかな何かが欠けている可能性がありますが、との違いはわかりませんstd::condition_variable_any。なぜ両方が必要なのですか?

4

2 に答える 2

27

違いは、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 で停止要求を受け入れるようになったwaitwait_forおよびメンバー関数を調べます。wait_until

または、最新の jthread と停止トークン C++20 提案リビジョンをチェックしてください

于 2012-01-06T13:28:18.623 に答える
20

std::condition_variableはより特化されているため、 の柔軟性が必要ない場合はより効率的ですstd::condition_variable_any

N3290 §30.5[thread.condition]/1 から

Classcondition_variableは、 type のオブジェクトでのみ待機できる条件変数を提供し、unique_lock<mutex>一部のプラットフォームで最大の効率を実現します。クラスcondition_variable_anyは、ユーザー指定のロック タイプのオブジェクトを待機できる一般的な条件変数を提供します。

実際、LLVM の libc++ では、shared_mutex でcondition_variable_anyより特殊化された (pthread_cond_t を使用する) を使用して実装されています。condition_variable

于 2012-01-06T13:16:38.637 に答える