C++笔记-mutex

一、mutex 到底是什么?锁还是信号量?

mutex 是一把"互斥锁"(不是信号量,虽然有点像)。

  • 名字来源:mut ual ex clusion(互斥
  • 作用:同一时间只允许一个线程进入某段代码
  • 它是一个对象std::mutex 是个类,你 mtx_ 就是它的一个实例)

mutex vs 信号量(区别)

mutex(互斥锁) 信号量(semaphore)
允许几个线程 1 个(0 或 1) N 个(0~N)
所有权 谁锁的谁解锁 没这要求
比喻 一个厕所隔间(一次进 1 人) 有 N 个隔间的厕所

mutex 可以看成"计数为 1 的信号量 ",但语义更严(有所有权)。你项目用 mutex(一次只让一个线程改哈希表)。

mutex 是怎么"互斥"的

mutex 对象内部有个状态("锁着"还是"没锁"):

  • lock():如果没锁 → 锁上,进去;如果已锁 → (挂起)
  • unlock():解锁,唤醒一个等待的线程
cpp 复制代码
线程A: lock() → 成功(现在锁着)→ 干活 → unlock()
线程B: lock() → 已锁 → 等...  等A unlock → 成功 → 干活

二、mutex 和 lock_guard 是什么关系?

mutex 是"锁本身",lock_guard 是"自动管理锁的助手"。

cpp 复制代码
mutex      = 门锁(实体)
lock_guard = 帮你"进门锁上、出门自动开锁"的管家

关系lock_guard 包装 一个 mutex,调用它的 lock/unlock

cpp 复制代码
std::lock_guard<std::mutex> lock(mtx_);
//   ↑ 管家            ↑ 它管的那把锁

展开看(lock_guard 内部做的事):

cpp 复制代码
// 构造时:帮你锁
mtx_.lock();
// ... 你的代码 ...
// 析构时:自动解锁
mtx_.unlock();

为什么需要管家? 因为手动 lock/unlock 容易忘解锁 (导致死锁)。管家保证一定解锁

对比:mutex 是"工具 ",lock_guard 是"用工具的省心方式"。

三、const 是什么,为什么 const 函数里不能锁

const 的含义

const 修饰成员函数 = "这个函数不修改对象的内容"(只读)。

cpp 复制代码
size_t size() const {   // 承诺:不改 KvHash 的内容
    return size_;       // 只读,OK
}

为什么 const 函数里不能锁

关键const 函数里,所有成员都变成 const(因为函数承诺不改它们)。

cpp 复制代码
size_t size() const {
    // 这里 mtx_ 是 const std::mutex
    mtx_.lock();
    //   ↑ lock() 会"修改" mtx_ 的状态(锁上)
    //     但 mtx_ 是 const → 不允许修改 → 报错
}

为什么锁算"修改"lock() 会改变 mutex 的内部状态(从"没锁"到"锁着")。这是"修改成员"。而 const 函数承诺"不改任何成员" → 冲突。

解决:mutable

cpp 复制代码
mutable std::mutex mtx_;

mutable = "这个成员即使在 const 函数里也允许被修改"。

为什么锁该用 mutable

  • const 函数承诺"不改逻辑内容"(不改数据)
  • 加锁/解锁只是"物理状态"变化,不改变数据
  • 所以锁用 mutable标准做法

几乎所有"带锁的类",锁成员都写 mutable

四、总结图

cpp 复制代码
mutex       = 一把锁(互斥,一次进1个线程)
              ↓ 被包装
lock_guard  = 自动上锁/解锁的管家(构造上锁,析构解锁)
              ↓ 用在
const 函数  = 承诺不改内容,但锁要 mutable 才能用

一句话

  • mutex = 一把互斥锁(不是信号量;一次只让 1 个线程进)
  • lock_guard = 包装 mutex 的管家,构造上锁、析构解锁(防忘记)
  • const 函数 承诺不改成员,锁会改 mutex 状态 → 冲突 → 加 mutable 让锁在 const 函数里也能用
相关推荐
beijixinghe1 小时前
第15节 指针作为函数参数的工程实战用法
开发语言·c++·c++基础·c++入门·几何引擎c++
j7~1 小时前
【C++微服务项目开发脚手架】(准备篇)从 0 到跑通:Docker 容器开发环境 + 宿主机用户 + Trae 远程连接 全链路踩坑实战
linux·c++·学习·xshell·docker容器·trae
唠玖馆1 小时前
C++11
c++
云泽8084 小时前
从零搭建 WSL2 + Ubuntu C/C++ 开发环境:原理、实践与底层架构解析
linux·c++·windows·ubuntu·wsl2
初願致夕霞10 小时前
C++11:类型推导与完美转发复盘笔记
c++
小猪写代码10 小时前
C++中什么是类,什么是对象
c++
钓鱼的肝14 小时前
梳理(1-5)
c++·经验分享·笔记·算法·青少年编程
jimy115 小时前
readelf 查看“派生类”的vtable符号
开发语言·c++
蒸蒸yyyyzwd15 小时前
cpp 选手秋招学习笔记 day37 面经学习
c++·八股