33.9.3 Barriers (thread.barrier)
編集バリアは、各フェーズが最大で期待されるスレッドの数までブロックされるスレッドの数をブロックするスレッド調整メカニズムです。
33.9.3.1 General (thread.barrier.general)
編集- 概要
-
- バリアは、複数のスレッドによって処理される繰り返しタスクを管理するためのスレッド調整メカニズムです。
- 各フェーズでは、期待されるスレッド数までスレッドがブロックされ、その数が到達するまで待機します。
33.9.3.2 Header <barrier> synopsis (barrier.syn)
編集- 概要
<barrier>
ヘッダーには、バリアを実装するためのクラステンプレートが含まれています。- クラステンプレート:
std::barrier
- クラステンプレート:
- テンプレートパラメータ
CompletionFunction
については後述します。
33.9.3.3 Class template barrier (thread.barrier.class)
編集std::barrier
クラステンプレート-
- メンバー関数
-
explicit barrier(ptrdiff_t expected, CompletionFunction f = CompletionFunction())
- バリアオブジェクトを初期化し、最初のフェーズを開始します。
~barrier()
- バリアオブジェクトを破棄します。
arrival_token arrive(ptrdiff_t update = 1)
- バリアに到達し、指定された更新数だけ期待されるスレッド数を減少させます。
void wait(arrival_token&& arrival) const
- 到達トークンに関連付けられた同期ポイントでブロックし、フェーズ完了ステップが実行されるのを待ちます。
void arrive_and_wait()
- 到達し、待機します。
void arrive_and_drop()
- 到達し、ブロックを解除します。
- メンバー変数
-
CompletionFunction completion
- 完了関数
- 動作
- バリアの各フェーズは以下の手順で構成されます:
- 期待されるカウントは、
arrive
またはarrive_and_drop
の呼び出しによって減少します。 - 期待されるカウントがゼロになった後、
arrive
、arrive_and_drop
、またはwait
の呼び出し中に、スレッドが1回だけ完了ステップを実行します。 - 完了ステップが完了すると、期待されるカウントは、コンストラクタの
expected
引数で指定された値にリセットされ、次のフェーズが開始されます。
- 期待されるカウントは、
- 各フェーズはフェーズ同期ポイントを定義し、そのフェーズでバリアに到達したスレッドは、
wait
を呼び出してフェーズ完了ステップが実行されるまでブロックされます。 - フェーズ完了ステップは、次の効果を持ちます:
- 完了関数を呼び出します(
completion()
と同等)。 - フェーズ同期ポイントでブロックされているすべてのスレッドのブロックを解除します。
- 完了関数を呼び出します(
std::barrier
のメンバー関数の同時呼び出しは、データ競合を導入しません。arrive
およびarrive_and_drop
は、アトミックに実行されます。- CompletionFunction
CompletionFunction
は、Cpp17MoveConstructible
とCpp17Destructible
の要件を満たさなければなりません。is_nothrow_invocable_v<CompletionFunction&>
はtrue
でなければなりません。- テンプレートパラメータ
CompletionFunction
のデフォルト値は、特定の型で、CompletionFunctionの要件を満たすと同時に、Cpp17DefaultConstructible
の要件を満たし、completion()
が効果を持たないものです。 - arrival_token
std::barrier::arrival_token
は、Cpp17MoveConstructible
、Cpp17MoveAssignable
、およびCpp17Destructible
の要件を満たす未指定の型です。- その他
static constexpr ptrdiff_t max() noexcept
: サポートされている最大の期待カウントを返します。arrive
やarrive_and_drop
の呼び出しは、フェーズ完了ステップの開始前に実行されることがあります。