C++如何使用std::condition_variable实现线程同步

轻婷小哥_9769

轻婷小哥_9769

2026-08-03

163人浏览

原创

std::condition_variable必须与std::mutex配合使用,且仅接受std::unique_lock;等待需用带谓词的wait()防虚假唤醒,notify选择取决于语义,生产环境应优先使用带超时的wait_for()/wait_until()。

c++如何使用std::condition_variable实现线程同步

std::condition_variable必须和std::mutex一起用

单独声明std::condition_variable却不用锁,线程会直接崩溃或触发未定义行为。它不管理共享状态,只负责“等待”和“通知”,状态保护必须由外部std::mutex承担。

常见错误是写成:cv.wait()前没加锁,或者用std::mutex以外的锁(比如std::shared_mutex)——std::condition_variable只接受std::unique_lock<:mutex></:mutex>。

  • 必须用std::unique_lock<:mutex></:mutex>传入wait(),不能用std::lock_guard
  • std::unique_lock构造时要传入已上锁的std::mutex,或让它自动加锁
  • 条件检查必须在wait()的lambda里做,且该lambda返回true才退出等待

wait()里的predicate不能省略

写cv.wait(lock)(无谓词版本)极容易导致虚假唤醒后逻辑错乱。POSIX和C++标准都允许wait()在没被notify_one()或notify_all()调用时返回,这叫spurious wakeup。

正确做法是把“是否该继续执行”的判断逻辑放进lambda:

cv.wait(lock, [&ready]() { return ready; });

这个lambda会在每次从等待中醒来时重新求值。如果返回false,它会自动重新进入等待并再次释放锁;如果返回true,才继续往下走。

  • 别把ready改成ready == true——冗余且易出错
  • lambda捕获要用[&]或显式按引用捕获,确保看到最新值
  • 变量ready本身必须是std::atomic<bool></bool>或受同一互斥锁保护,否则读写竞争

notify_one()和notify_all()的区别很实际

用notify_one()还是notify_all()不是风格选择,而是语义决定的:前者只唤醒一个等待线程,后者唤醒所有。选错会导致死锁或资源浪费。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

典型场景:

  • 生产者-消费者中,一个新任务到来,只需唤醒一个空闲消费者 → 用notify_one()
  • 状态变更影响所有等待者(如关闭标志置位、全局配置更新)→ 用notify_all()
  • 多个线程等同一个条件但各自处理不同数据,用notify_one()更高效;若条件满足后所有线程都要重试检查,就得用notify_all()

注意:notify_*调用本身不要求持有锁,但通常放在修改共享状态的临界区末尾,保证等待线程醒来时看到一致状态。

别忘了wait_for()和wait_until()的超时处理

没有超时的wait()可能永远卡住——比如通知丢失、逻辑缺陷、或对方线程提前退出。生产代码几乎都应该用带超时的版本。

wait_for()适合固定等待时间(如“最多等100ms”),wait_until()适合绝对时间点(如“等到某个deadline”):

if (cv.wait_for(lock, 100ms, [&ready]() { return ready; })) {
    // 真正被notify唤醒
} else {
    // 超时,需检查是否仍需等待或放弃
}
  • 超时返回false不代表失败,只是“没等到”,业务逻辑要自己判断下一步
  • 超时时间单位用std::chrono类型,别传整数毫秒——cv.wait_for(lock, 100)会编译不过
  • 即使超时,lambda仍会被执行一次,所以条件检查逻辑不能有副作用

真正麻烦的是多条件组合等待、嵌套锁、或需要响应中断的场景——这些std::condition_variable不解决,得靠std::stop_token或自定义信号机制补足。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2208

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

979

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

407

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

386

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1197

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1305

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习