constexpr explicit
barrier(ptrdiff_t expected,
CompletionFunction f = CompletionFunction()); // (1)
barrier(const barrier&) = delete; // (2)
barrierオブジェクトの構築
- (1) :
barrier
オブジェクトの初期化を行う。 - (2) : コピーコンストラクタ。コピー不可。
説明のため、ここではバリアオブジェクトが保持するCompletionFunction
型のメンバ変数をcompletion
と表記する。
事前条件
expected >= 0
かつ expected <= max()
効果
各バリアフェーズの初期予定カウントと、初回フェーズにおける現行予定カウントの両方にexpected
を設定する。
completion
をstd::move(f)
で初期化する。
初回フェーズを開始する。
例外
CompletionFunction
型のムーブコンストラクタが投げた例外
備考
expected
を0
として初期化したバリアオブジェクトでは、破棄以外の操作を行えない。
例
#include <barrier>
#include <iostream>
#include <thread>
#include <mutex>
// 行単位cout出力用ロックを返す(対応コンパイラ登場までの暫定措置)
// C++20で追加されたstd::osyncstreamの方が好ましい。
// std::osyncstream(std::cout) << ...;
auto lk() {
static std::mutex cout_mtx;
return std::unique_lock{cout_mtx};
}
int main() {
// (完了関数なし)バリアを定義
std::barrier<> sync1{2};
// 完了関数付きのバリアを定義
std::barrier sync2{2, []{
// 完了関数はバリアに関与するいずれか一つのスレッド上でのみ実行されること保証される
std::cout << "finished @" << std::this_thread::get_id() << std::endl;
}};
// 並行実行されるタスクを定義
auto task = [&]{
lk(), std::cout << "phase-1 @" << std::this_thread::get_id() << std::endl;
sync2.arrive_and_wait();
lk(), std::cout << "phase-2 @" << std::this_thread::get_id() << std::endl;
sync2.arrive_and_wait();
lk(), std::cout << "phase-3 @" << std::this_thread::get_id() << std::endl;
sync1.arrive_and_wait();
};
// タスクを2並行実行
std::thread t{task};
task();
t.join();
}
出力例
phase-1 @140171090683648
phase-1 @140171067340544
finished @140171067340544
phase-2 @140171067340544
phase-2 @140171090683648
finished @140171090683648
phase-3 @140171090683648
phase-3 @140171067340544
バージョン
言語
- C++20
処理系
- Clang: 11.0 ✅
- GCC: ??
- ICC: ??
- Visual C++: ??