std:: barrier
|
定义于头文件
<barrier>
|
||
|
template
<
class
CompletionFunction
=
/* see below */
>
class barrier ; |
(C++20 起) | |
类模板
std::barrier
提供一种线程协调机制,它会阻塞已知大小的线程组,直至该组中所有线程都到达屏障。与
std::latch
不同,屏障可重复使用:一旦到达的线程组被解除阻塞,该屏障即可重复使用。与
std::latch
不同,屏障会在解除线程阻塞前执行一个可能为空的可调用对象。
屏障对象的生命周期包含一个或多个阶段。每个阶段定义一个
阶段同步点
,等待线程会在此阻塞。线程可以通过调用
arrive
到达屏障但延迟等待
阶段同步点
。此类线程后续可通过调用
wait
在
阶段同步点
上阻塞。
屏障的 阶段 包含以下步骤:
-
每次调用
arrive或arrive_and_drop时, 期望计数 会递减。 -
当期望计数降为零时,将执行
阶段完成步骤
,即调用
completion,并解除所有在阶段同步点阻塞的线程。完成步骤的结束 强发生于 所有因完成步骤而解除阻塞的调用返回之前。
在期望计数达到零后,某个线程在其调用arrive、arrive_and_drop或wait期间会精确执行一次完成步骤,但若没有线程调用wait,该步骤是否执行由实现定义。 -
当完成步骤结束时,期望计数被重置为构造时指定的值减去自那时起对
arrive_and_drop的调用次数,并开始下一个 屏障阶段 。
对
barrier
成员函数(析构函数除外)的并发调用不会引入数据竞争。
目录 |
模板参数
| CompletionFunction | - | 函数对象类型 |
-
CompletionFunction
必须满足
MoveConstructible
与
Destructible
的要求。
std::
is_nothrow_invocable_v
<
CompletionFunction
&
>
必须为
true
。
|
||
CompletionFunction
的默认模板实参是一个未指定的函数对象类型,该类型额外满足
可默认构造
要求。调用其左值无参版本不产生任何效果。
成员类型
| 名称 | 定义 |
arrival_token
|
满足 MoveConstructible 、 MoveAssignable 和 Destructible 要求的未指定对象类型 |
数据成员
| 成员 | 定义 |
CompletionFunction
completion
|
在每次阶段完成步骤时调用的完成函数对象
( 仅用于说明的成员对象* ) |
成员函数
构造一个
barrier
(公开成员函数) |
|
销毁
barrier
(公开成员函数) |
|
|
operator=
[deleted]
|
barrier
不可赋值
(公开成员函数) |
|
到达屏障并递减期望计数
(公开成员函数) |
|
|
在阶段同步点阻塞,直到其阶段完成步骤运行
(公开成员函数) |
|
|
到达屏障并将期望计数减一,然后阻塞直到当前阶段完成
(公开成员函数) |
|
|
将后续阶段的初始期望计数和当前阶段的期望计数各减一
(公开成员函数) |
|
常量 |
|
|
[static]
|
实现支持的期望计数的最大值
(公开静态成员函数) |
注释
| 功能测试 宏 | 值 | 标准 | 功能 |
|---|---|---|---|
__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 = "... 完成\n" "正在清理...\n"; std::cout << phase; phase = "... 完成\n"; }; std::barrier sync_point(std::ssize(workers), on_completion); auto work = [&](std::string name) { std::string product = " " + name + " 已完成工作\n"; std::osyncstream(std::cout) << product; // 正确,op<< 调用是原子操作 sync_point.arrive_and_wait(); product = " " + name + " 已完成清理\n"; std::osyncstream(std::cout) << product; sync_point.arrive_and_wait(); }; std::cout << "开始执行...\n"; std::vector<std::jthread> threads; threads.reserve(std::size(workers)); for (auto const& worker : workers) threads.emplace_back(work, worker); }
可能的输出:
开始执行... Anil 已完成工作 Carl 已完成工作 Busara 已完成工作 ... 完成 正在清理... Busara 已完成清理 Carl 已完成清理 Anil 已完成清理 ... 完成
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| P2588R3 | C++20 | 原有的阶段完成保证可能阻碍硬件加速 | 已放宽 |
参见
|
(C++20)
|
一次性线程屏障
(类) |