Namespaces
Variants

std:: condition_variable

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
condition_variable
(C++11)
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
定義済みヘッダー <condition_variable>
class condition_variable ;
(C++11以降)

std::condition_variable は、 std::mutex と共に使用される同期プリミティブであり、1つ以上のスレッドを、別のスレッドが共有変数( 条件 )を変更し、かつ std::condition_variable に通知するまでブロックします。

共有変数を変更しようとするスレッドは以下の要件を満たさなければなりません:

  1. std::mutex を取得する(通常は std::lock_guard を使用)。
  2. ロックを所有している間に共有変数を変更する。
  3. std::condition_variable に対して notify_one または notify_all を呼び出す(ロック解放後でも可)。

共有変数がアトミックであっても、変更を待機中のスレッドに 正しく 公開するためには、ミューテックスを所有している間に変更する必要があります。

std::condition_variable を待機する意図があるスレッドは、以下を満たさなければなりません:

  1. 共有変数を保護するために使用されるミューテックスに対して std:: unique_lock < std:: mutex > を取得します。
  2. 以下のいずれかを実行します:
  1. 条件が既に更新され通知済みでないか確認する。
  2. std::condition_variable に対して wait wait_for 、または wait_until を呼び出す(ミューテックスをアトミックに解放し、条件変数が通知されるか、タイムアウトが発生するか、 spurious wakeup が発生するまでスレッド実行を停止し、その後ミューテックスをアトミックに取得してから戻る)。
  3. 条件を確認し、満たされていない場合は待機を再開する。
または:
  1. 述語付きオーバーロード版の wait wait_for 、および wait_until を使用する。これは前述の3つのステップと同じ処理を実行する。

std::condition_variable std:: unique_lock < std:: mutex > とのみ動作し、一部のプラットフォームでは最大の効率を実現します。 std::condition_variable_any は、 BasicLockable オブジェクト(例: std::shared_lock など)と動作する条件変数を提供します。

条件変数は、 wait wait_for wait_until notify_one および notify_all メンバー関数の同時呼び出しを許可します。

クラス std::condition_variable StandardLayoutType です。これは CopyConstructible でも MoveConstructible でも CopyAssignable でも MoveAssignable でもありません。

目次

ネスト型

名前 定義
native_handle_type implementation-defined

メンバー関数

オブジェクトを構築する
(public member function)
オブジェクトを破棄する
(public member function)
operator=
[deleted]
コピー代入不可
(public member function)
通知
待機中の1つのスレッドに通知する
(public member function)
待機中の全てのスレッドに通知する
(public member function)
待機
条件変数が通知されるまで現在のスレッドをブロックする
(public member function)
条件変数が通知されるか、指定されたタイムアウト時間が経過するまで現在のスレッドをブロックする
(public member function)
条件変数が通知されるか、指定された時刻に達するまで現在のスレッドをブロックする
(public member function)
ネイティブハンドル
ネイティブハンドルを返す
(public member function)

std::condition_variable std::mutex と組み合わせて使用され、スレッド間通信を容易にします。

#include <condition_variable>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
    // main()がデータを送信するまで待機
    std::unique_lock lk(m);
    cv.wait(lk, []{ return ready; });
    // 待機後、ロックを所有
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
    // データをmain()に返送
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
    // 手動ロック解除は通知前に実行され、待機スレッドが
    // 再度ブロックされるのを防ぐ(詳細はnotify_oneを参照)
    lk.unlock();
    cv.notify_one();
}
int main()
{
    std::thread worker(worker_thread);
    data = "Example data";
    // ワーカースレッドにデータを送信
    {
        std::lock_guard lk(m);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();
    // ワーカーの完了を待機
    {
        std::unique_lock lk(m);
        cv.wait(lk, []{ return processed; });
    }
    std::cout << "Back in main(), data = " << data << '\n';
    worker.join();
}

出力:

main() signals data ready for processing
Worker thread is processing data
Worker thread signals data processing completed
Back in main(), data = Example data after processing

関連項目

任意のロック型に関連付けられた条件変数を提供する
(クラス)
(C++11)
基本的な相互排他機能を提供する
(クラス)
(C++11)
厳密なスコープベースのミューテックス所有権ラッパーを実装する
(クラステンプレート)
移動可能なミューテックス所有権ラッパーを実装する
(クラステンプレート)