[C++] 上锁、解锁、获取锁、释放锁的区别

一、前言

在学多线程与互斥锁的时候,经常被一些概念搞混淆,上锁、解锁、获得锁、释放锁。同时有些时候,又很疑惑

cpp 复制代码
{
    lock_guard<mutex> lock(mtx);
	shared_data = 42;
}

想上面这一段代码,字面意思咋一看,就是对mtx上锁,锁住了,但是既然锁住了那为什么shared_data又可以被访问呢?

本文将针对上面这些概念进行彻底地梳理。

二、上锁、解锁、获得锁、释放锁

首先,上锁可以像我们生活中的上锁一样进行理解,一旦一个线程被上锁了,那么它就动不了啦。

然后就是重头戏,也是最难理解的啦

上锁完毕后,线程会一直阻塞住,直到=="获得通行证"之后才可以继续往下运行。这里的获取通行证其实就是获得锁==。

而上锁是在lock_guard构造函数内调用的,如果有空闲的锁被当前线程拿到就会进入 获得锁 状态后,然后构造函数就完成了

以如下代码段为例:

cpp 复制代码
{
    lock_guard<mutex> lock(mtx);
	shared_data = 42;
}

"获取锁"中的锁就是mtx(std::mutex类型变量),任何线程只有在获得锁之后才可以继续往下运行(这里是C++里面这么规定的,尽管与我们日常生活不太一样,日常生活中,获得锁三个看起来就像是被一把锁给锁住了,然后就应该被阻塞住了不能继续往下运行了。但是就这么理解吧,把"获得锁"看成"获得通行证")

然后就是解锁(它与上锁相对应)了,它是在析构函数里面进行调用的,一旦调用完成,就会进行释放锁状态

最后就是释放锁了,其实也可以理解成 释放通行证,当一个线程释放锁(通行证)之后,其他被阻塞的线程才可以去争抢这个锁(通行证)

对上面进行一个总结,可以用如下的因果链来记忆:

cpp 复制代码
// 完整生命周期
上锁(动作)  → 获取锁(状态)  → 持有锁期间  → 解锁(动作)  → 释放锁(状态)
   ↓              ↓                              ↓              ↓
尝试获取    成功获得所有权                   主动放弃     所有权转移
cpp 复制代码
{
    std::lock_guard<std::mutex> guard(mtx);  
    // 构造时:上锁 → 获取锁(原子操作)
    
    // ... 临界区(持有锁状态)...
    shared_data = 42;
    
}  // 析构时:解锁 → 释放锁(原子操作)

三、代码理解

最后,还有一个点需要说一下,这里的代码std::lock_guard<std::mutex> guard(mtx);

在理解的时候可以这么理解,这把锁在上锁过程中(获取锁之前)是锁住自己线程的,一旦获得锁之后,就是去锁住其他线程的

cpp 复制代码
{
    // 锁自己
    std::lock_guard<std::mutex> guard(mtx);  
    // 构造时:上锁 → 获取锁(原子操作)
    
    // 锁其他人
 
    // ... 临界区(持有锁状态)...
    shared_data = 42;
    
}  // 析构时:解锁 → 释放锁(原子操作)
// 释放被锁的其他人
相关推荐
今儿敲了吗6 小时前
Python——函数基础
开发语言·笔记·python
CHANG_THE_WORLD6 小时前
深入理解递归:从函数调用到调用栈的完整执行过程
java·开发语言·算法
kels88996 小时前
单连接动态增减订阅:股票行情API后端降负载实战方案
开发语言·笔记·python·信息可视化·金融
一拳一个呆瓜7 小时前
【STL】iostream 编程:使用提取运算符
c++·stl
a4493153627 小时前
MacBook USB-C不充电故障诊断:从PD握手到主板供电链路
c语言·开发语言·macos·电脑
德福危险7 小时前
从目录枚举到bash破壳漏洞、从流量抓包到组权限提权:靶机练习之symfonos3
开发语言·bash
meng半颗糖7 小时前
3.Java流程控制语句
java·开发语言·intellij-idea
影寂ldy7 小时前
C# WinForm 三种自定义控件 + 完全自定义重绘控件知识点
开发语言·c#
学逆向的7 小时前
汇编——寻址方式
开发语言·汇编·网络安全
大模型码小白7 小时前
企业级检索增强后端集成:Java 服务如何管理知识库版本
java·服务器·开发语言·人工智能·python·microsoft