latch是一次性同步工具,用于等待计数归零后释放所有线程,适用于单次等待场景;barrier支持重复使用,允许多轮同步,适合周期性或分阶段的并行任务。

在C++20中,latch 和 barrier 是新增的两种同步原语,用于简化多线程编程中的等待逻辑。它们都属于“栅栏”类同步机制,但用途和行为有所不同。
latch(闩锁)是一种一次性使用的同步工具,允许一个或多个线程等待,直到某个计数器递减到零。一旦计数归零,所有等待的线程被释放,且 latch 不可重用。
主要操作包括:
常见使用场景是主线程启动多个工作线程后,等待它们全部完成。
立即学习“C++免费学习笔记(深入)”;
// 示例:使用 std::latch 等待所有线程完成
void worker(int id, std::latch& latch) {
std::cout << "Worker " << id << " is working...\n";
// 模拟工作
std::this_thread::sleep_for(std::chrono::milliseconds(100 * (id + 1)));
latch.count_down(1); // 完成任务,计数减一
}
int main() {
const int N = 3;
std::latch latch(N);
std::vector<std::thread> workers;
for (int i = 0; i < N; ++i) {
workers.emplace_back(worker, i, std::ref(latch));
}
latch.wait(); // 主线程等待所有 worker 完成
std::cout << "All workers done!\n";
for (auto& w : workers) w.join();
return 0;
}
barrier(屏障)支持重复使用,允许多个线程在某个点汇合。当指定数量的线程调用 arrive() 或 arrive_and_wait() 后,所有线程被同时释放,并可重新开始下一轮同步。
与 latch 不同的是,barrier 可以循环使用,适合周期性同步场景,比如多阶段并行算法。
关键操作:
completion 函数会在每次所有线程会合后执行一次,通常用于重置状态或切换阶段。
// 示例:使用 std::barrier 实现两阶段并行任务
void stage_worker(int id, std::barrier<>& phase_barrier) {
// 第一阶段
std::cout << "Worker " << id << " finishing stage 1\n";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
phase_barrier.arrive_and_wait(); // 等待所有线程完成第一阶段
// 第二阶段
std::cout << "Worker " << id << " finishing stage 2\n";
std::this_thread::sleep_for(std::chrono::milliseconds(50));
phase_barrier.arrive_and_wait(); // 等待第二阶段完成
}
int main() {
const int N = 3;
std::barrier<> barrier(N);
std::vector<std::thread> workers;
for (int i = 0; i < N; ++i) {
workers.emplace_back(stage_worker, i, std::ref(barrier));
}
for (auto& w : workers) w.join();
std::cout << "All phases completed.\n";
return 0;
}
选择哪种同步机制取决于你的需求:
注意:两者都不是锁,不保护共享数据,仅用于控制线程执行顺序。
基本上就这些。C++20 的 latch 和 barrier 让常见的并发模式变得更简洁安全,减少了手写条件变量和互斥量的复杂度。
以上就是C++20的同步原语latch和barrier怎么用_C++多线程编程中的栅栏同步机制的详细内容,更多请关注php中文网其它相关文章!
编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号