namespace std {
class latch;
}
概要
latch
クラスは、ラッチ通過/到達スレッドが期待する個数になるまで複数スレッドの進行をブロックする、スレッド調整機構(同期プリミティブ)である。
ラッチは1つのカウンタで状態管理される同期プリミティブとみなせる。カウンタは0
以上かつ初期値以下の値をとり、このカウンタ値がラッチ未到達のスレッド個数と解釈される。
その動作仕様からカウントダウン・ラッチと呼ばれることもある。
- コンストラクタにてカウンタ値を設定する。
count_down()
によりカウンタ値の減算と通知を行う。(ラッチ通過)wait()
によりカウンタ値が0
になるまで呼び出しスレッドをブロックする。(ラッチ待機)arrive_and_wait()
はcount_down()
+wait()
に相当する。(ラッチ到達 兼 待機)
ラッチオブジェクトは1回だけ使用でき、カウンタ値が0
に到達したオブジェクトの再利用はできない。
複数スレッド間同期を繰り返しとる場合はバリアbarrier
を利用する。
ラッチlatch
はカウンタ値0
を待機するが、類似機構のセマフォcounting_semaphore
はカウンタ値が0
より大きいことを待機するという違いがある。
メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
(constructor) |
コンストラクタ | C++20 |
(destructor) |
デストラクタ | C++20 |
operator=(const latch&) = delete; |
代入演算子 | C++20 |
count_down |
通過通知 | C++20 |
try_wait |
カウンタ値が0 か否かを確認 |
C++20 |
wait |
待機処理 | C++20 |
arrive_and_wait |
到達通知と待機処理 | C++20 |
静的メンバ関数
名前 | 説明 | 対応バージョン |
---|---|---|
max |
処理系でサポートされるカウンタ最大値 | C++20 |
例
#include <iostream>
#include <latch>
#include <mutex>
#include <thread>
constexpr int NWORKER = 3; // ワーカ数
std::mutex cout_mtx; // 行単位cout出力用ミューテックス
int main()
{
// 1回だけ初期化される共有データ
int shared_data = 0;
// 初期化済みを表すラッチ: 初期カウント値=1
std::latch initialized{1};
// タスク完了を表すラッチ: 初期カウント値=ワーカ数+1(メインスレッド)
std::latch completed{NWORKER+1};
// ワーカスレッド群をFire-and-Forget起動
for (int id = 1; id <= NWORKER; id++) {
std::thread([&,id]{
// 共有データの初期化完了を待機
initialized.wait();
// メインスレッド上でのshared_data代入完了は保証されており、
// 以降はshared_data読出のみであればデータ競合発生しない。
int local_data = shared_data;
{ // ワーカスレッドのタスクを実行
std::lock_guard lk{cout_mtx};
std::cout << "Worker#" << id << ":" << local_data << std::endl;
}
// タスク完了を通知
completed.count_down();
// ワーカスレッドはブロックされずそのまま終了する
}).detach();
}
// 共有データを初期化
shared_data = 42;
// 共有データ初期化完了をワーカスレッド群へ通知
initialized.count_down();
// メインスレッドはブロックされず後続行を実行する
{ // メインスレッドのタスクを実行
std::lock_guard lk{cout_mtx};
std::cout << "Main:" << shared_data << std::endl;
}
// メインスレッドのタスク完了通知 兼 全ワーカスレッドのタスク完了待機
completed.arrive_and_wait();
}
55
std::cout << "Worker#" << id << ":" << local_data << std::endl;
#include <iostream>
#include <latch>
#include <mutex>
#include <thread>
constexpr int NWORKER = 3; // ワーカ数
std::mutex cout_mtx; // 行単位cout出力用ミューテックス
int main()
{
// 1回だけ初期化される共有データ
int shared_data = 0;
// 初期化済みを表すラッチ: 初期カウント値=1
std::latch initialized{1};
// タスク完了を表すラッチ: 初期カウント値=ワーカ数+1(メインスレッド)
std::latch completed{NWORKER+1};
出力例
Worker#1:42
Worker#2:42
Main:42
Worker#3:42
バージョン
言語
- C++20
処理系
- Clang: 11.0 ✅
- GCC: ??
- ICC: ??
- Visual C++: ??