名前空間
変種
操作

std::condition_variable

提供: cppreference.com
< cpp‎ | thread
 
 
スレッドサポートライブラリ
スレッド
(C++11)
this_thread 名前空間
(C++11)
(C++11)
(C++11)
相互排他
(C++11)
汎用ロック管理
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
条件変数
condition_variable
(C++11)
(C++11)
フューチャー
(C++11)
(C++11)
(C++11)
(C++11)
 
 
ヘッダ <condition_variable> で定義
class condition_variable;
(C++11およびそれ以降)

condition_variable クラスは、別のスレッドが共有変数 (状態) を変更し condition_variable を通知するまで、1つまたは同時に複数のスレッドをブロックするために使用することができます。

変数を変更するつもりのスレッドは、以下のようにする必要があります。

  1. (一般的には std::lock_guard を使用して) std::mutex を取得し、
  2. ロックを保持している間に変更を行い、
  3. std::condition_variable に対して notify_one または notify_all を実行します (通知ためにロックを保持している必要はありません)。

共有変数がアトミックな場合でも、待機しているスレッドに変更を正しく公開するためには、ミューテックスの保護下で変更しなければなりません。

std::condition_variable で待機するつもりのスレッドは、以下のようにする必要があります。

  1. 共有変数を保護するために使用しているのと同じミューテックスの std::unique_lock<std::mutex> を取得し、
  2. wait, wait_for または wait_until を実行します。 wait 操作は自動的にミューテックスを解放し、スレッドの実行を停止します。
  3. 条件変数が通知されるか、タイムアウトが満了するか、 spurious wakeup が発生すると、スレッドは起床し、ミューテックスは自動的に再取得されます。 その後、条件を確認し、起床が spurious であれば待機を再開します。

std::condition_variablestd::unique_lock<std::mutex> と組み合わせてのみ使用できます。 いくつかのプラットフォームではこの制限により最大の効率を発揮できます。 std::condition_variable_any を使用すれば、 BasicLockable な任意のオブジェクト、例えば std::shared_lock と組み合わせて使用できます。

メンバ関数 waitwait_forwait_untilnotify_onenotify_all は並行的に呼び出すことができます。

クラス std::condition_variableStandardLayoutType です。 CopyConstructible でも MoveConstructible でも CopyAssignable でも MoveAssignable でもありません。

目次

[編集] メンバ型

メンバ型 定義
native_handle_type 処理系定義

[編集] メンバ関数

オブジェクトを構築します
(パブリックメンバ関数) [edit]
オブジェクトを破棄します
(パブリックメンバ関数) [edit]
operator=
[削除]
コピー代入可能ではありません
(パブリックメンバ関数) [edit]
通知
待機中のスレッドひとつに通知します
(パブリックメンバ関数) [edit]
待機中のスレッドすべてに通知します
(パブリックメンバ関数) [edit]
待機
条件変数が通知されるまで現在のスレッドをブロックします
(パブリックメンバ関数) [edit]
条件変数が通知されるか指定時間が経過するまで現在のスレッドをブロックします
(パブリックメンバ関数) [edit]
条件変数が通知されるか指定時点に達するまで現在のスレッドをブロックします
(パブリックメンバ関数) [edit]
ネイティブハンドル
ネイティブハンドルを返します
Original:
returns the native handle
The text has been machine-translated via Google Translate.
You can help to correct and verify the translation. Click here for instructions.

(パブリックメンバ関数) [edit]

[編集]

スレッド間通信のために std::mutex と組み合わせて condition_variable を使用します。

#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
 
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
 
void worker_thread()
{
    // Wait until main() sends data
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return ready;});
 
    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";
 
    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";
 
    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}
 
int main()
{
    std::thread worker(worker_thread);
 
    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard<std::mutex> lk(m);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();
 
    // wait for the worker
    {
        std::unique_lock<std::mutex> 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