0

0

C++中如何利用std::scoped_lock一次性安全锁定多个互斥量?(死锁预防)

冰火之心

冰火之心

发布时间:2026-03-04 09:01:09

|

662人浏览过

|

来源于php中文网

原创

c++中如何利用std::scoped_lock一次性安全锁定多个互斥量?(死锁预防)

std::scoped_lock 构造时就完成全部加锁,失败则自动回滚

它不是“先锁一个、再锁下一个”,而是在构造函数里尝试一次性获取所有互斥量的所有权;只要任意一个锁不可用(比如已被其他线程持有),它会立即释放已成功获取的锁,并抛出 std::system_error(错误码为 std::errc::resource_deadlock_would_occur 仅在检测到死锁风险时触发,实际更常见的是阻塞等待或超时失败)。这意味着你不用手动写 try-catch + 解锁逻辑来防死锁。

  • 必须传入可拷贝/可移动的互斥量对象(std::mutexstd::recursive_mutex 等),不能传指针或引用
  • 构造成功后,析构时自动按逆序解锁(与构造时加锁顺序无关,内部已排序)
  • 若使用 std::defer_lock 标签,构造时不加锁,需后续调用 lock() —— 这就失去了一次性防死锁的意义,慎用

为什么不能用 std::lock_guard 锁多个 mutex?

std::lock_guard 只接受单个互斥量,强行套多个会导致编译失败:error: no matching constructor。有人试图写两个 std::lock_guard,但顺序不一致就会埋下死锁隐患:

std::lock_guard<std::mutex> g1(mtx_a); // 线程1先a后b
std::lock_guard<std::mutex> g2(mtx_b);

而另一处代码反着来:

ChatGPT Writer
ChatGPT Writer

免费 Chrome 扩展程序,使用 ChatGPT AI 生成电子邮件和消息。

下载
std::lock_guard<std::mutex> g2(mtx_b); // 线程2先b后a → 死锁风险
  • std::scoped_lock 内部调用 std::lock,后者采用“先升序排列地址再尝试加锁”的策略,从语言层面规避了锁序依赖
  • C++17 起才支持多参数构造;C++14 只能用 std::lock + 多个 std::lock_guard 手动管理,容易漏解锁

std::scoped_lock 的超时控制:用 std::chrono 配合 try_lock_for

原生 std::scoped_lock 不支持超时,但你可以退一步用 std::unique_lock + std::defer_lock 组合实现类似效果,不过那就脱离“一次性安全锁定”的初衷了。真要超时,推荐直接上 std::scoped_lock 的替代方案:

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

  • 先用 std::try_to_lock 标签构造 std::scoped_lock,它会非阻塞尝试获取所有锁,失败则构造失败(owns_lock() == false
  • 需要带超时的场景,改用 std::unique_lock 分别调用 try_lock_for(),再用 std::lock 做兜底 —— 但这手动步骤多了,容易出错
  • 注意:std::scoped_lock 没有 try_lock_until 成员函数,别在它身上找

容易忽略的兼容性细节:递归锁、shared_mutex 和 move-only 类型

std::scoped_lock 支持 std::recursive_mutex,但不支持 std::shared_mutexstd::shared_timed_mutex(因为它们的 lock 接口签名不同,不满足 Lockable 概念要求)。另外,如果你传入的是 move-only 的自定义锁类型(比如包装了 std::unique_lock 的 RAII 类),它可能无法编译通过 —— 因为 std::scoped_lock 构造时会对每个参数做 copy/move,而 move-only 类型只能 move 一次。

  • 确认所有互斥量类型都满足 Lockable:即提供 lock()unlock()try_lock() 且无异常
  • 避免混用 std::mutexstd::shared_mutex 在同一个 std::scoped_lock 中 —— 编译报错,错误信息通常是 no matching function for call to 'lock'
  • 调试时留意 std::scoped_lock 的生命周期:它必须比所有被锁的资源活得久,否则析构时可能访问已销毁的 mutex
实际写的时候,最常踩的坑是把互斥量变量声明在局部作用域却忘了它是被 std::scoped_lock 引用的——一旦 mutex 提前析构,std::scoped_lock 析构时调用 unlock() 就会 UB。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

411

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

368

2023.10.25

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

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

1774

2023.10.19

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

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

570

2025.10.17

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

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

2340

2025.12.29

java接口相关教程
java接口相关教程

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

44

2026.01.19

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

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

723

2023.08.10

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

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

723

2023.08.10

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

3

2026.03.03

热门下载

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

精品课程

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

共94课时 | 10.6万人学习

C 教程
C 教程

共75课时 | 5.1万人学习

C++教程
C++教程

共115课时 | 20.3万人学习

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

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