讲师中心 微信公众号
AI工具推荐 视频效率加速

C++怎么避免死锁_C++多线程安全教程【预防】

夜墨小哥_1403

夜墨小哥_1403

发布时间:2026-03-12 20:01:03

|

437人浏览过

|

来源于php中文网

原创

死锁必然发生于两线程循环等待对方持有的锁;C++无运行时检测,std::mutex卡住即永久挂起;须按固定顺序加锁,优先用std::scoped_lock防顺序错误,但不解决粒度与跨函数问题。

c++怎么避免死锁_c++多线程安全教程【预防】

死锁不是“会不会发生”,是“什么时候触发”

只要两个线程各自持有对方需要的锁、又同时申请对方的锁,死锁就必然发生。C++ 里没有运行时检测机制,std::mutex 一旦卡住,程序就永久挂起——连超时重试都做不到。

常见错误现象:std::thread 阻塞在 lock() 或 std::scoped_lock 构造里,CPU 占用归零,调试器显示所有相关线程停在 __pthread_mutex_lock;用 gdb 查栈能看到多个线程互相等待不同 std::mutex 实例。

  • 永远按**固定全局顺序**获取多个锁:比如所有函数都先锁 mutex_a 再锁 mutex_b,哪怕当前逻辑“看起来”只该先动 b
  • 用 std::scoped_lock 替代手写多个 lock() 调用:它内部自动按地址排序加锁,避免顺序依赖出错
  • 绝不混合使用 lock() / try_lock() 和 std::scoped_lock:前者可能部分成功后者全失败,逻辑断裂点极难追踪

std::scoped_lock 不是万能解药

std::scoped_lock 确实能防“同一批锁”的顺序死锁,但它不解决锁粒度、生命周期或跨函数调用链的问题。

使用场景:保护同一数据结构的多个成员变量,或需原子更新两个关联资源(如账户余额 + 交易日志)。

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

参数差异:std::scoped_lock 构造时若任一锁不可得,会阻塞直到全部可得;而 std::try_lock 返回 -1 表示失败,但你得自己处理回滚逻辑。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 别把它当“更安全的 lock_guard”:如果只传一个锁,std::scoped_lock 和 std::lock_guard 行为一致,但前者开销略大
  • 不能跨作用域释放:锁在 scoped_lock 对象析构时才释放,别试图提前 unlock() —— 它没这个接口
  • 和 std::unique_lock 混用要小心:后者支持延迟加锁、条件变量、转移所有权,但手动管理多了,出错概率反而上升

std::shared_mutex 在读多写少时反而加重死锁风险

很多人以为“读锁不互斥”就能随便加,结果在混合读写场景下栽跟头:一个线程持 shared_lock,另一个线程持 unique_lock 等写锁,第三个线程又想拿 shared_lock —— 这时写锁线程被堵,读锁线程又等不到写锁释放,形成环路。

性能影响:Linux 下 std::shared_mutex 实现通常基于 futex,但公平性差;高并发读+偶发写时,新来的读请求可能饿死写线程。

  • 只在明确满足“读操作远多于写操作 + 读操作耗时短”时才用,否则老实用 std::mutex
  • 禁止在持有 shared_lock 期间调用可能升级为写的函数(比如某个 getter 内部悄悄触发 lazy init)
  • 不要嵌套:在已持 shared_lock 的函数里再尝试拿 unique_lock,等于主动制造死锁条件

std::condition_variable::wait 里的隐式锁释放是最大陷阱

wait() 会自动释放锁、挂起线程,唤醒后重新加锁——这一步看似省事,实则把锁的边界藏起来了。一旦 predicate 检查逻辑有误,或者唤醒信号丢失,线程就可能永远等下去。

错误现象:生产者调用了 notify_one(),消费者却没醒来;或者消费者醒来了,但数据还没准备好,又立刻回去等。

  • 必须用 while 循环检查 predicate:while (!ready) cv.wait(lock);,不用 if
  • notify 必须在修改共享状态后、且仍在同一把锁保护下发出,否则存在竞态窗口
  • 别在 wait 前做耗时操作:比如先查数据库再等条件变量,会导致锁持有时间过长,拖慢其他线程

真正难的不是写对第一版多线程代码,而是改需求时——加个字段、换种通知方式、拆个类——这些动作会悄悄破坏原有的锁顺序或条件判断。每次改动后,用 helgrind 或 ThreadSanitizer 扫一遍,比靠人脑推演靠谱得多。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
while的用法
while的用法

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

354

2023.09.25

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2581

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

356

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

397

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

452

2026.05.09

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3168

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

4969

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3789

2025.12.29

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn