std:: barrier
|
定義済みヘッダー
<barrier>
|
||
|
template
<
class
CompletionFunction
=
/* see below */
>
class barrier ; |
(C++20以降) | |
クラステンプレート
std::barrier
は、既知のサイズのスレッドグループがバリアに到達するまでそのグループをブロックするスレッド調整メカニズムを提供します。
std::latch
とは異なり、バリアは再利用可能です:到着したスレッドグループのブロックが解除されると、バリアは再利用できます。
std::latch
とは異なり、バリアはスレッドのブロック解除前に空の可能性もある呼び出し可能オブジェクトを実行します。
バリアオブジェクトのライフタイムは1つ以上のフェーズで構成されます。各フェーズは
フェーズ同期ポイント
を定義し、待機スレッドはここでブロックします。スレッドはバリアに到着できますが、
arrive
を呼び出すことで
フェーズ同期ポイント
での待機を延期できます。このようなスレッドは後で
wait
を呼び出すことで
フェーズ同期ポイント
でブロックできます。
バリアの phase は以下のステップで構成されます:
-
期待カウント
は、
arriveまたはarrive_and_dropの各呼び出しによってデクリメントされます。 -
期待カウントがゼロに達すると、
フェーズ完了ステップ
が実行されます。つまり、
completionが呼び出され、フェーズ同期ポイントでブロックされているすべてのスレッドがブロック解除されます。完了ステップの終了は、 strongly happens-before 完了ステップによってブロック解除されたすべての呼び出しが戻る前に発生します。
期待カウントがゼロに達した後、正確に1回、スレッドがarrive、arrive_and_dropまたはwaitの呼び出し中に完了ステップを実行します。ただし、どのスレッドもwaitを呼び出さない場合にステップが実行されるかどうかは実装定義です。 -
完了ステップが終了すると、期待カウントは構築時に指定された値から、それ以降の
arrive_and_dropの呼び出し回数を減じた値にリセットされ、次の バリアフェーズ が開始されます。
barrier
のメンバー関数(デストラクタを除く)の同時呼び出しは、データ競合を引き起こしません。
目次 |
テンプレートパラメータ
| CompletionFunction | - | 関数オブジェクト型 |
-
CompletionFunction
は
MoveConstructible
および
Destructible
の要件を満たさなければならない。
std::
is_nothrow_invocable_v
<
CompletionFunction
&
>
は
true
でなければならない。
|
||
CompletionFunction
のデフォルトテンプレート引数は、
さらに
DefaultConstructible
の要件を満たす未規定の関数オブジェクト型です。
引数なしでその左辺値を呼び出しても効果はありません。
メンバー型
| 名前 | 定義 |
arrival_token
|
要件 MoveConstructible 、 MoveAssignable および Destructible を満たす未規定のオブジェクト型 |
データメンバ
| メンバー | 定義 |
CompletionFunction
completion
|
各フェーズ完了ステップで呼び出される完了関数オブジェクト
( 説明専用メンバーオブジェクト* ) |
メンバー関数
barrier
を構築する
(public member function) |
|
barrier
を破棄する
(public member function) |
|
|
operator=
[deleted]
|
barrier
は代入不可
(public member function) |
|
バリアに到着し、期待カウントを減少させる
(public member function) |
|
|
フェーズ完了ステップが実行されるまで、フェーズ同期ポイントでブロックする
(public member function) |
|
|
バリアに到着し、期待カウントを1減少させた後、現在のフェーズが完了するまでブロックする
(public member function) |
|
|
後続フェーズの初期期待カウントと現在のフェーズの期待カウントの両方を1減少させる
(public member function) |
|
定数 |
|
|
[static]
|
実装でサポートされる期待カウントの最大値
(public static member function) |
注記
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_barrier
|
201907L
|
(C++20) |
std::barrier
|
202302L
|
(C++20)
(DR) |
フェーズ完了の緩和された保証 |
例
#include <barrier> #include <iostream> #include <string> #include <syncstream> #include <thread> #include <vector> int main() { const auto workers = {"Anil", "Busara", "Carl"}; auto on_completion = []() noexcept { // ここではロックは不要 static auto phase = "... done\n" "Cleaning up...\n"; std::cout << phase; phase = "... done\n"; }; std::barrier sync_point(std::ssize(workers), on_completion); auto work = [&](std::string name) { std::string product = " " + name + " worked\n"; std::osyncstream(std::cout) << product; // OK, op<< 呼び出しはアトミック sync_point.arrive_and_wait(); product = " " + name + " cleaned\n"; std::osyncstream(std::cout) << product; sync_point.arrive_and_wait(); }; std::cout << "Starting...\n"; std::vector<std::jthread> threads; threads.reserve(std::size(workers)); for (auto const& worker : workers) threads.emplace_back(work, worker); }
出力例:
Starting... Anil worked Carl worked Busara worked ... done Cleaning up... Busara cleaned Carl cleaned Anil cleaned ... done
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| P2588R3 | C++20 | 旧フェーズ完了保証がハードウェアアクセラレーションを妨げる可能性あり | 緩和済み |
関連項目
|
(C++20)
|
単回使用スレッドバリア
(クラス) |