std::condition_variable
From cppreference.com
| ヘッダ <condition_variable> で定義 |
||
| class condition_variable; |
(C++11以降) | |
std::condition_variableは、1つ以上のスレッドをブロックするためにstd::mutexと組み合わせて使用される同期プリミティブです。このブロックは、別スレッドが共有変数(条件)を変更してstd::condition_variableに通知するまで続きます。
共有変数を変更しようとするスレッドは、以下を行う必要があります。
- std::mutexを取得します(通常はstd::lock_guardを介して)。
- ロックを所有している間に共有変数を変更します。
std::condition_variableに対してnotify_oneまたはnotify_allを呼び出します(ロックを解放した後でも可能です)。
共有変数がアトミックであっても、待機中のスレッドに変更を正しく公開するために、mutexを所有している間に変更する必要があります。
std::condition_variableで待機しようとするスレッドは、以下を行う必要があります。
- 共有変数を保護するために使用されるmutexに対するstd::unique_lock<std::mutex>を取得します。
- 以下のいずれかを行います。
- 条件を確認します。すでに更新および通知されている可能性があるためです。
std::condition_variableに対してwait、wait_for、またはwait_untilを呼び出します(mutexをアトミックに解放し、条件変数に通知されるか、タイムアウトするか、偽のウェイクアップが発生するまでスレッドの実行を中断します。その後、復帰する前にmutexをアトミックに取得します)。- 条件を確認し、満たされていない場合は待機を再開します。
- or
wait、wait_for、wait_untilの述語付きオーバーロードを使用します。これは同じ3つのステップを実行します。
std::condition_variableはstd::unique_lock<std::mutex>でのみ機能し、一部のプラットフォームでは最大限の効率を可能にします。std::condition_variable_anyは、std::shared_lockのような任意のBasicLockableオブジェクトで機能する条件変数を提供します。
条件変数は、`wait`、`wait_for`、`wait_until`、`notify_one`、`notify_all`の各メンバ関数を同時に呼び出すことを許可します。
クラスstd::condition_variableはStandardLayoutTypeです。CopyConstructible、MoveConstructible、CopyAssignable、またはMoveAssignableではありません。
目次 |
[編集] ネストされた型
| 名前 | 定義 |
native_handle_type
|
実装定義 |
[編集] メンバ関数
| オブジェクトを構築する (public member function) | |
| オブジェクトを破棄する (public member function) | |
| operator= [削除] |
コピー代入不可 (public member function) |
通知 | |
| 待機中のスレッドを1つ通知します。 (public member function) | |
| 待機しているすべてのスレッドに通知します (public member function) | |
待機 | |
| 条件変数が通知されるまで現在のスレッドをブロックする (public member function) | |
| 指定されたタイムアウト期間後、または条件変数(condition variable)が起動されるまで、現在のスレッドをブロックする。 (public member function) | |
| 指定された時刻に達するか、または条件変数(condition variable)が起動されるまで、現在のスレッドをブロックする。 (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() { // wait until main() sends data std::unique_lock 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 lk(m); ready = true; std::cout << "main() signals data ready for processing\n"; } cv.notify_one(); // wait for the worker { 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) |
基本的な相互排他機能を提供する (クラス) |
| (C++11) |
厳密なスコープベースのミューテックス所有権ラッパーを実装する (クラステンプレート) |
| (C++11) |
ムーブ可能なミューテックス所有権ラッパーを実装する (クラステンプレート) |