Namespaces
Variants

std:: barrier

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
barrier
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
定義済みヘッダー <barrier>
template < class CompletionFunction = /* see below */ >
class barrier ;
(C++20以降)

クラステンプレート std::barrier は、既知のサイズのスレッドグループがバリアに到達するまでそのグループをブロックするスレッド調整メカニズムを提供します。 std::latch とは異なり、バリアは再利用可能です:到着したスレッドグループのブロックが解除されると、バリアは再利用できます。 std::latch とは異なり、バリアはスレッドのブロック解除前に空の可能性もある呼び出し可能オブジェクトを実行します。

バリアオブジェクトのライフタイムは1つ以上のフェーズで構成されます。各フェーズは フェーズ同期ポイント を定義し、待機スレッドはここでブロックします。スレッドはバリアに到着できますが、 arrive を呼び出すことで フェーズ同期ポイント での待機を延期できます。このようなスレッドは後で wait を呼び出すことで フェーズ同期ポイント でブロックできます。

バリアの phase は以下のステップで構成されます:

  1. 期待カウント は、 arrive または arrive_and_drop の各呼び出しによってデクリメントされます。
  2. 期待カウントがゼロに達すると、 フェーズ完了ステップ が実行されます。つまり、 completion が呼び出され、フェーズ同期ポイントでブロックされているすべてのスレッドがブロック解除されます。完了ステップの終了は、 strongly happens-before 完了ステップによってブロック解除されたすべての呼び出しが戻る前に発生します。
    期待カウントがゼロに達した後、正確に1回、スレッドが arrive arrive_and_drop または wait の呼び出し中に完了ステップを実行します。ただし、どのスレッドも wait を呼び出さない場合にステップが実行されるかどうかは実装定義です。
  3. 完了ステップが終了すると、期待カウントは構築時に指定された値から、それ以降の 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)
単回使用スレッドバリア
(クラス)