C++如何实现多线程递归锁 _ std::recursive_mutex用法【实战】

风萱君_2184

风萱君_2184

2026-04-08

984人浏览

原创

不能。std::recursive_mutex仅支持同一线程多次加锁/解锁,性能开销更大且无法防止逻辑级重入错误;仅当存在明确递归调用路径且需保护共享状态时才考虑使用,并优先重构为非递归设计。

c++如何实现多线程递归锁 _ std::recursive_mutex用法【实战】

std::recursive_mutex 能不能直接替代普通 mutex?

不能。普通 std::mutex 在同一线程中重复 lock() 会直接导致未定义行为(通常是程序崩溃或死锁),而 std::recursive_mutex 是唯一能安全支持“同一线程多次加锁、多次解锁”的标准互斥类型——但它不是万能的,性能开销更大,且无法防止逻辑级重入错误。

常见错误现象:std::terminate 被调用、线程卡死、ASan 报 double lock of a mutex;本质是误把 std::mutex 当作可重入用了。

  • 仅当函数存在**明确的递归调用路径**(比如树遍历、表达式求值、回调再触发自身)且需保护共享状态时,才考虑 std::recursive_mutex
  • 优先检查是否能重构为非递归设计(例如用显式栈代替函数调用栈)
  • std::recursive_mutex 不可与 std::unique_lock 或 std::shared_lock 混用非标准扩展(如某些平台的 shared_mutex 变体)

怎么正确声明、加锁和解锁?

声明方式和普通 mutex 完全一致,但语义不同:它记录当前持有线程 ID 和嵌套深度,每次 lock() 增加计数,每次 unlock() 减一,仅当计数归零才真正释放锁。

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

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

下载
class Counter {
    std::recursive_mutex mtx_;
    int value_ = 0;
public:
    void increment() {
        mtx_.lock();      // ✅ 允许同一线程内多次调用
        ++value_;
        if (value_ 
  • 必须成对使用 lock()/unlock(),不能混用 RAII(如 std::lock_guard)——因为 std::lock_guard 构造即 lock、析构即 unlock,只做一次,无法应对多层嵌套
  • 推荐改用 std::unique_lock<:recursive_mutex></:recursive_mutex>,它支持延迟锁定、手动 unlock() 和再 lock(),更灵活
  • 不要在异常路径中裸写 unlock();若可能抛异常,务必用 std::unique_lock 管理生命周期

std::unique_lock<:recursive_mutex> 怎么用才不出错?

这是实际项目中最稳妥的用法:既保留递归能力,又避免手动管理锁生命周期的风险。

void process_node(Node* n) {
    std::unique_lock<:recursive_mutex> lk(mutex_);
    if (!n) return;
    data_.push_back(n->val);
    if (n->left) process_node(n->left);  // 递归进入,lk 仍持有锁,但嵌套计数+1
    if (n->right) process_node(n->right);
    // lk 析构时自动按嵌套深度逐层 unlock,直到计数为 0
}</:recursive_mutex>
  • std::unique_lock 构造时默认调用 lock(),但也可传 std::defer_lock 延迟;注意它不支持拷贝,只支持移动
  • 若需在递归中途临时释放锁(比如调用外部不可控代码),可显式调用 lk.unlock(),之后还能 lk.lock() 回来——这在普通 std::lock_guard 下做不到
  • 性能提示:相比 std::mutex,std::recursive_mutex 每次 lock/unlock 都要读写线程 ID 和计数器,高竞争下开销明显;别为了“图省事”在非递归场景滥用

为什么 std::recursive_mutex 不能解决所有重入问题?

它只解决「同一线程重复加锁」的底层同步问题,但掩盖不了设计缺陷。比如两个函数 A 和 B 都持同一把 std::recursive_mutex,A 调用 B,B 又回调 A —— 这仍是逻辑死锁,std::recursive_mutex 会让它静默跑下去,结果数据错乱却无提示。

  • 典型陷阱:信号处理函数、GUI 事件回调、第三方库 hook 中意外触发原函数
  • 调试困难:gdb 看不到“锁被谁占着”,因为始终是同一个线程;需靠日志或计数器人工追踪嵌套深度
  • 跨平台兼容性没问题(C++11 起标准支持),但部分嵌入式 STL 实现可能阉割该类型,编译前应确认 __cpp_lib_recursive_mutex 宏存在

真正难的从来不是加几行锁,而是判断“这里到底该不该递归”以及“共享状态在多深的调用里还有效”。std::recursive_mutex 是把双刃剑,用之前先问一句:这个递归,真的必要吗?

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
c++怎么把double转成int
c++怎么把double转成int

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

2025.08.29

3448

10

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

2025.10.23

644

4

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

4967

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2228

6

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

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

2023.08.10

3718

6

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

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

2025.12.24

1049

20

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

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

2026.01.21

363

30

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

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

2026.01.21

519

24

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

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

2026.02.06

369

20

热门下载

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

精品课程

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

共0课时 | 0人学习

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

共0课时 | 0人学习

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

共0课时 | 0人学习