c++ barrier 使用详解
std::barrier c++20
- 头文件
#include <barrier>
。 - 作用:一般被用来协调多个线程,在所有线程都到达屏障点之后,才允许它们继续执行,对于需要线程间同步的并行算法和任务来说非常有用。
- 使用步骤:
- 创建 barrier 对象,并指定期待计数;
- 在线程中调用 arrive 或者 arrive_and_wait 方法,使期待计数减一;
- 当期待计数减为 0 后,即代表所有线程都已到达屏障点,barrier 会解除所有阻塞在屏障点上的线程并重置期待计数。
- 注意事项:
- 不同于 latch ,barrier 可重用;
- 同时调用 barrier 的成员函数,除了析构函数,不引入数据竞争;
- 在同一个线程中,可以多次减少期待计数;
std::barrier 成员函数
arrive
:到达屏障并减少期待计数。wait
:阻塞当前线程,直至期待计数减为 0。arrive_and_wait
:到达屏障并把期待计数减少一,然后阻塞直至期待计数减为 0。arrive_and_drop
:到达屏障并把期待计数减少一并使后续阶段的初始期待计数减一。
使用示例
-
线程 1 和 线程 2 先各自执行一些任务,然后在屏障点上等待直到所有线程抵达后再继续执行后续代码:
#include <cstdio> #include <thread> #include <vector> #include <barrier> using namespace std::literals; constexpr int num_threads = 2; std::barrier barrier(num_threads); std::vector<int> v1; std::vector<int> v2; void f1() { for (int i = 0; i < 2; i++) { v1.push_back(i); // 到达屏障点并阻塞 barrier.arrive_and_wait(); // 所有线程都到达屏障点后,继续执行 printf("v2[%d] = %d\n", i, v2[i]); } } void f2() { for (int i = 0; i < 2; i++) { v2.push_back(i); // 到达屏障点并阻塞 barrier.arrive_and_wait(); // 所有线程都到达屏障点后,继续执行 printf("v1[%d] = %d\n", i, v1[i]); } } int main() { std::jthread t1(f1); std::jthread t2(f2); return 0; }