std::shared_mutex、std::mutex和std::recursive_mutex是什么锁

std::shared_mutex。std::mutex和std::recursive_mutex是什么锁

锁类型 类型 核心特性 适用场景
std::shared_mutex 读写锁 读共享、写独占 读多写少
std::mutex 普通互斥锁 完全独占,不可递归 通用场景(90%的情况)
std::recursive_mutex 递归互斥锁 同一线程可重复加锁 递归函数、嵌套调用

详细对比

1. std::shared_mutex ------ 读写锁(C++17)
特性 说明
读模式 多个线程可同时持有共享锁,并发读取
写模式 只有一个线程可持有独占锁,写时禁止任何读
适用场景 读多写少(如配置缓存、路由表、DNS缓存)
性能 读并发高,但写操作开销比 mutex
RAII工具 std::shared_lock(读)、std::unique_lock(写)
cpp 复制代码
std::shared_mutex rw_mutex;
std::map<int, int> cache;

// 读操作:多个线程可并发
int read(int key) {
    std::shared_lock lock(rw_mutex);  // 共享锁
    return cache[key];
}

// 写操作:独占
void write(int key, int val) {
    std::unique_lock lock(rw_mutex);  // 独占锁
    cache[key] = val;
}
2. std::mutex ------ 普通互斥锁(C++11)
特性 说明
独占性 完全独占,同一时间只有一个线程能持有
递归 不支持,同一线程重复 lock() 会导致死锁
适用场景 90%的常规多线程场景
性能 最基础、性能最高
RAII工具 std::lock_guardstd::unique_lock
cpp 复制代码
std::mutex mtx;
int counter = 0;

void increment() {
    std::lock_guard lock(mtx);  // 自动加锁解锁
    ++counter;
}
3. std::recursive_mutex ------ 递归互斥锁(C++11)
特性 说明
独占性 独占,但同一线程可重复加锁
递归 支持,内部维护计数器,加锁几次就要解锁几次
适用场景 递归函数、嵌套调用中需要加锁的场景
性能 mutex 略低(需维护线程ID和计数)
注意 容易掩盖设计缺陷,能不用就不用
cpp 复制代码
std::recursive_mutex rec_mtx;

void funcA() {
    std::lock_guard lock(rec_mtx);  // 第一次加锁
    funcB();                        // 内部再次加锁,不会死锁
}

void funcB() {
    std::lock_guard lock(rec_mtx);  // 第二次加锁(同一线程)
}

对比总结

维度 std::mutex std::recursive_mutex std::shared_mutex
C++版本 C++11 C++11 C++17
独占性 ✅ 独占 ✅ 独占 ✅ 写独占,❌ 读共享
递归 ❌ 不支持 ✅ 支持 ❌ 不支持
读并发 ❌ 不支持 ❌ 不支持 ✅ 支持
性能 最高 略低 读场景高,写场景低
RAII工具 lock_guard / unique_lock lock_guard / unique_lock shared_lock(读) / unique_lock(写)
适用场景 通用 递归/嵌套调用 读多写少

选择建议

  1. 默认首选std::mutex + std::lock_guard
  2. 读多写少std::shared_mutex + std::shared_lock(读)/ std::unique_lock(写)
  3. 递归调用std::recursive_mutex(但优先考虑重构代码避免递归加锁)
相关推荐
炸膛坦客10 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
旖-旎10 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
灯澜忆梦10 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-10 小时前
C#中的StringBuilder相关方法
开发语言·c#
To_OC11 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
Henry Zhu12311 小时前
C++中的特殊成员函数与智能指针
c++
-银雾鸢尾-11 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
delishcomcn11 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹12 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
大模型码小白12 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程