std::barrier(3)
π std::barrier(3) π
okay bestie, welcome to std::barrier(3) from the C++ Standard Libary β yes, that's the manual name up top, and we're about to make thread coordination feel like a group chat where everybody actually shows up. π
πΈ NAME πΈ
std::barrier - std::barrier
β¨ Synopsis β¨
Defined in header <barrier>
template< class CompletionFunction = /* see below */ > (since C++20)
class barrier;
The class template std::barrier provides a thread-coordination mechanism that blocks a group of threads of known size until all threads in that group have reached the barrier. Unlike std::latch, barriers are reusable: once a group of arriving threads are unblocked, the barrier can be reused. Unlike std::latch, barriers execute a possibly empty callable before unblocking threads.
A barrier object's lifetime consists of one or more phases. Each phase defines a phase synchronization point where waiting threads block. Threads can arrive at the barrier, but defer waiting on the phase synchronization point by calling arrive. Such threads can later block on the phase synchronization point by calling wait.
A barrier phase consists of the following steps:
- The expected count is decremented by each call to
arriveorarrive_and_drop. - When the expected count reaches zero, the phase completion step is run, meaning that the completion is invoked, and all threads blocked on the phase synchronization point are unblocked. The end of the completion step strongly happens-before all calls that were unblocked by the completion step return. Exactly once after the expected count reaches zero, a thread executes the completion step during its call to
arrive,arrive_and_drop, orwait, except that it is implementation-defined whether the step executes if no thread callswait. - When the completion step finishes, the expected count is reset to the value specified at construction less the number of calls to
arrive_and_dropsince, and the next barrier phase begins.
Concurrent invocations of the member functions of barrier, except for the destructor, do not introduce data races.
π§ Template parameters π§
CompletionFunctionβ a function object type.CompletionFunctionmust meet the requirements ofMoveConstructibleandDestructible.std::is_nothrow_invocable_v<CompletionFunction&>must betrue.- The default template argument of
CompletionFunctionis an unspecified function object type that additionally meets the requirements ofDefaultConstructible. Calling an lvalue of it with no arguments has no effects.
π Member objects π
completion(private) β a completion function object of typeCompletionFunctionwhich is called on every phase completion step. (exposition-only member object*)
π¦ Member types π¦
arrival_tokenβ an unspecified object type meeting requirements ofMoveConstructible,MoveAssignableandDestructible.
π Member functions π
constructorβ constructs a barrier (public member function)destructorβ destroys the barrier (public member function)operator=βbarrieris not assignable[deleted](public member function)arriveβ arrives at barrier and decrements the expected count (public member function)waitβ blocks at the phase synchronization point until its phase completion step is run (public member function)arrive_and_waitβ arrives at barrier and decrements the expected count by one, then blocks until current phase completes (public member function)arrive_and_dropβ decrements both the initial expected count for subsequent phases and the expected count for current phase by one (public member function)
β Constants β
max[static]β the maximum value of expected count supported by the implementation (public static member function)
π Notes π
- Feature-test macro:
__cpp_lib_barrier- Value:
201907L - Std:
(C++20) - Feature:
std::barrier
- Value:
- Feature-test macro:
__cpp_lib_barrier- Value:
202302L - Std:
(C++20) - Feature:
Relaxed guarantees for phase completion(DR)
- Value:
π₯ Example π₯
// Run this code
#include <barrier>
#include <iostream>
#include <string>
#include <syncstream>
#include <thread>
#include <vector>
int main()
{
const auto workers = {"Anil", "Busara", "Carl"};
auto on_completion = []() noexcept
{
// locking not needed here
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<< call is
atomic
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);
}
π Possible output: π
Starting...
Anil worked
Carl worked
Busara worked
... done
Cleaning up...
Busara cleaned
Carl cleaned
Anil cleaned
... done
π Defect reports π
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
- DR
P2588R3β Applied to:C++20; Behavior as published: "old phase completion guarantees might prevent hardware acceleration"; Correct behavior:relaxed.
π See also π
latchβ single-use thread barrier (C++20) (class)
xoxo π β source/version/date from the footer: http://cppreference.com, 2024.06.10, and the page is std::barrier(3) π periodt π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms