C++中std::latch和std::barrier有什么区别_C++20多线程同步屏障【并发】-C++

std::latch是一次性同步原语,不可重用;std::barrier支持多轮同步且可配置回调函数,但回调不得抛异常。两者参与线程数均在构造时固定,不可动态调整。

std::latch 和 std::barrier 都只能触发一次吗?

不是。std::latch 是一次性同步点:构造时指定计数 count,每次调用 count_down() 减一,减到 0 后所有等待线程被唤醒,之后再调用 wait() 会立即返回,count_down() 也不再有效 —— 它不可重用。std::barrier 则默认支持重复使用:每次所有参与线程调用 arrive_and_wait()(或配对的 arrive() + wait())后,计数重置为初始值,可进入下一轮同步。

常见错误现象:误把 std::latch 当作循环屏障用,在 for 循环里反复 wait(),结果第二轮起直接“穿透”,线程不同步。

  • 若需单次汇聚(如:主线程等所有工作线程初始化完成),用 std::latch
  • 若需多轮协同(如:并行计算的每一轮迭代都需全体就绪),必须用 std::barrier
  • std::barrier 构造时可传入一个回调函数(std::function),在每轮计数归零、唤醒前执行 —— std::latch 没有该能力

它们的 arrive() / count_down() 行为有何关键差异?

std::latch::count_down() 只是减计数,不阻塞;std::barrier::arrive() 也是非阻塞到达,但返回一个 std::barrier::arrival_token,配合 wait() 才构成“到达并等待”。而 std::barrier::arrive_and_wait() 是原子操作:它既完成到达,又阻塞直到本轮所有线程都到达。

容易踩的坑:

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

  • 对 std::latch 调用 count_down() 多次,可能提前触发唤醒,且无法撤回
  • 对 std::barrier 混用 arrive() 和 arrive_and_wait():比如线程 A 调用 arrive(),线程 B 调用 arrive_and_wait(),B 会等 A 再调一次 wait() —— 但 A 并没调,导致死锁
  • std::barrier 的 arrive() 返回的 token 必须被某个线程用于 wait(),否则该轮无法完成(除非所有线程都用 arrive_and_wait())

性能和内存开销谁更轻量?

std::latch 实现通常更简单:内部只需一个原子计数器 + 一个 futex 或条件变量。C++20 标准允许其实现为无锁(lock-free)结构,多数编译器(如 libstdc++、libc++)对其做了优化。

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » C++中std::latch和std::barrier有什么区别_C++20多线程同步屏障【并发】-C++
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4019129+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1393+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4019130+
  • 本周更新: 0+
  • 最后更新: 2026-03-16