0

0

C++如何使用std::barrier同步多线程?(C++20协作机制)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-24 16:56:03

|

140人浏览过

|

来源于php中文网

原创

std::barrier构造时必须预先指定固定参与线程数,不可动态增减;需严格匹配arrive()调用次数,否则卡死或抛异常;支持arrive_and_drop()主动退出,但drop后不可再arrive;无超时wait,不支持轮询,适用多轮同步场景。

c++如何使用std::barrier同步多线程?(c++20协作机制)

std::barrier 构造时必须指定参与线程数

它不是“自动感知线程数量”的同步点,而是靠构造时传入的 expected 值硬编码等待人数。一旦构造完成,这个值就固定了,不能增减线程——想动态调整就得换用 std::latch 或手写逻辑。

常见错误是把 std::barrier 当成可重用的“信号量”,结果某次 arrive() 后没线程再调用,后续 wait() 就永远卡住;或者误以为能在线程启动后才决定人数,实际必须在所有线程共享 barrier 实例前就定死。

  • 初始化时传 4,就必须恰好有 4 个线程调用 arrive() 才会集体释放
  • 少于 4 次调用 → 卡死;多于 4 次 → std::system_error(错误码为 std::errc::invalid_argument
  • 若线程可能提前退出,得配合 arrive_and_drop() 主动减少计数,否则 barrier 永远等不满

arrive() 和 arrive_and_drop() 的行为差异很关键

arrive() 是常规抵达:计数减一,若归零则触发所有等待线程继续,并重置内部计数器(barrier 可重复使用);arrive_and_drop() 则是“永久退群”——不仅减一,还把 expected 值也减一,后续再没人能凑满原定人数。

典型场景是 worker 线程池中某些任务提前失败需撤离:不 drop 就会导致剩余线程永远等不到它,整个 barrier 卡住;但滥用 drop 又会让 barrier 提前释放,破坏同步语义。

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

Paraflow
Paraflow

AI产品设计智能体

下载
  • 正常协作流程用 arrive()
  • 线程确定不再参与后续同步轮次时,用 arrive_and_drop()
  • drop 后不能再对这个 barrier 调用 arrive(),否则未定义行为

wait() 阻塞直到所有预期线程到达,且无超时版本

std::barrier 没有带 timeout 的 wait_for()wait_until(),只有阻塞式 wait()。这意味着一旦逻辑出错(比如漏调 arrive()),线程就彻底挂起,无法靠超时探测问题。

调试时容易忽略这点,尤其在异常路径里忘了调 arrive()。建议在关键路径用 RAII 包装,比如局部对象在析构时自动 arrive(),避免裸调用遗漏。

  • 没有 try_wait(),不能轮询
  • 不能用在需要响应中断或取消的场景(如 std::jthread 的 stop_token 不直接兼容 barrier)
  • 若需超时控制,得在外层加 std::condition_variable + std::mutex 自行实现,代价不小

与 std::latch 和 std::semaphore 的适用边界

std::barrier 的核心价值是“多轮复用+自动重置”,而 std::latch 是一次性倒计时,std::counting_semaphore 更偏向资源计数而非线程协作。选错类型会导致逻辑别扭甚至死锁。

比如做 N 个线程分阶段计算:第一阶段全做完才能进第二阶段,且要循环 10 轮——这时 std::barrier 最自然;如果只等一次初始化完成,std::latch 更轻量;如果控制的是数据库连接数这类资源,则该用 std::counting_semaphore

  • 需要“到达即重置、反复用” → std::barrier
  • 只需“等一次、之后永远满足” → std::latch
  • 需要 acquire/release 资源配额,或跨线程传递许可 → std::counting_semaphore

barrier 的重置行为是隐式的,也是最容易被忽视的复杂点:它不靠用户手动 reset,而是在每次计数归零后自动准备好下一轮。但这个“自动”依赖所有线程严格遵守约定——少一次 arrive(),后面所有轮次全崩。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

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

719

2023.08.10

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

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

371

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

25

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

100

2026.02.06

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

376

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2094

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

356

2023.08.31

Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

1

2026.02.24

热门下载

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

精品课程

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

共94课时 | 10.1万人学习

C 教程
C 教程

共75课时 | 4.9万人学习

C++教程
C++教程

共115课时 | 19.2万人学习

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

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