0

0

c++20的std::barrier和std::latch如何用于线程同步? (多线程协作)

尼克

尼克

发布时间:2026-01-13 16:20:02

|

790人浏览过

|

来源于php中文网

原创

该用std::latch时用于一次性同步,如主线程等待所有工作线程完成;该用std::barrier时用于多轮循环同步,如并行迭代中每轮等待所有线程到达。

c++20的std::barrier和std::latch如何用于线程同步? (多线程协作)

std::barrierstd::latch 是 C++20 引入的轻量级同步原语,专为“等待一组线程到达某个点”而设计。它们比 std::mutex + std::condition_variable 更简洁、更高效,且无所有权语义(不绑定线程),适合一次性或循环式协作场景。

什么时候该用 std::latch

std::latch 是一次性计数器:初始化后只能递减(count_down())和等待(wait()),不可重置、不可重复使用。典型用于“主线程等所有工作线程完成”这类单次汇聚场景。

  • 常见错误:在 latch 已触发(count == 0)后再次调用 count_down() —— 行为未定义;调用 wait() 后再调用 count_down() 也无效
  • 使用场景:std::thread 启动多个任务,主线程用 latch.wait() 阻塞直到全部结束;或作为 std::jthread 的启动栅栏(配合 std::stop_token 初始化)
  • 性能影响:无锁实现(通常基于原子操作),开销远低于条件变量;但不能复用,反复创建/销毁有分配成本
std::latch done(3);
std::thread t1([&]{ /* work */ done.count_down(); });
std::thread t2([&]{ /* work */ done.count_down(); });
std::thread t3([&]{ /* work */ done.count_down(); });

done.wait(); // 主线程阻塞,直到三次 count_down 完成 t1.join(); t2.join(); t3.join();

什么时候该用 std::barrier

std::barrier 是可重用的同步点,每次所有参与线程调用 arrive()(或 arrive_and_wait())后自动重置计数,进入下一轮。适合多阶段并行计算,比如迭代算法中的每轮同步。

  • 常见错误:混用 arrive()arrive_and_wait() —— 若部分线程只调用 arrive(),其余线程调用 arrive_and_wait(),则可能死锁(前者不阻塞,后者会等全部到达)
  • 参数差异:std::barrier 构造时可传入回调函数std::barrier b(n, []{ /* once per phase */ });),该回调在每轮计数归零后、重置前由**恰好一个**到达线程执行(常用于更新共享状态或检查终止条件)
  • 兼容性注意:MSVC 19.30+、GCC 11+、Clang 12+ 支持;旧版本需手动回退到 std::condition_variable
std::barrier sync(4);
std::vector workers;
for (int i = 0; i < 4; ++i) {
    workers.emplace_back([&sync]{
        for (int round = 0; round < 3; ++round) {
            // 每轮独立计算
            do_work(round);
            sync.arrive_and_wait(); // 等其他 3 个线程也到达
        }
    });
}
for (auto& t : workers) t.join();

为什么不用 std::condition_variable 替代?

不是不能,而是容易出错且冗余。用条件变量模拟 latch 需要手动管理互斥量、计数器、通知逻辑;模拟 barrier 还得处理重入、唤醒丢失、虚假唤醒等问题。

无界AI
无界AI

一站式AI创作、搜索、分享服务

下载

立即学习C++免费学习笔记(深入)”;

  • 易踩的坑:notify_one() 写成 notify_all() 可能引发惊群;忘记在 wait() 前加 while 循环检查条件;互斥量粒度太粗导致串行化严重
  • 性能差异:条件变量涉及内核态切换,std::barrier/std::latch 在多数情况下纯用户态完成(尤其计数未达阈值时仅原子操作)
  • 语义清晰性:latch.wait() 就是“等全部完成”,barrier.arrive_and_wait() 就是“我到了,大家一起进下一轮”——意图直白,不易误用

实际协作中容易忽略的细节

两者都要求所有参与线程**严格调用相同次数**的同步操作,否则要么永远等待,要么未定义行为。没有运行时校验,编译器也不会报错。

  • std::latch 的初始计数值必须等于预期调用 count_down() 的总次数;少一次 → 永不触发;多一次 → UB
  • std::barrier 的参与线程数在构造时固定,运行时增减线程需额外协调(例如用 std::shared_ptr<:barrier> 并配合引用计数)
  • 异常安全:若线程在到达前抛异常,未调用 arrive()count_down(),整个同步将卡死——必须确保这些调用在 try/catch 或 RAII 包装器中完成

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.20

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

84

2023.09.25

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

60

2025.12.01

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

399

2023.08.14

PPT交互图表教程大全
PPT交互图表教程大全

本专题整合了PPT交互图表相关教程汇总,阅读专题下面的文章了解更多详细内容。

39

2026.01.12

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

19

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 3万人学习

Excel 教程
Excel 教程

共162课时 | 11.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号