讲师中心 微信公众号
AI工具推荐 视频效率加速

C++中lock_guard怎么用_C++多线程自动加锁解锁机制【并发】

风芳小哥_2192

风芳小哥_2192

发布时间:2026-02-05 16:07:53

|

448人浏览过

|

来源于php中文网

原创

lock_guard 是栈上自动管理互斥量生命周期的 RAII 类模板,构造时加锁、析构时解锁,确保异常安全;不能 new、不能 return、不能作类成员,因其禁止拷贝/移动且依赖栈对象生命周期。

c++中lock_guard怎么用_c++多线程自动加锁解锁机制【并发】

lock_guard 是什么,为什么不能直接 new 或 return

lock_guard 是一个栈上自动管理互斥量生命周期的 RAII 类模板,它在构造时加锁、析构时解锁。它的核心价值不是“加锁”,而是“确保锁一定被释放”——哪怕中间抛异常、提前 return 或 goto 跳出作用域,析构函数仍会被调用。

所以你不能:
- new lock_guard<mutex>(m)</mutex>:堆分配对象不会自动析构
- return lock_guard<mutex>(m)</mutex>:返回临时对象会触发移动/拷贝,而 lock_guard 明确删除了拷贝和移动构造函数(编译报错:use of deleted function)
- 把它作为类成员变量长期持有:它不拥有 mutex,也不负责管理其生命周期,只管“这一段代码执行期间”的锁定

最常用写法:在作用域开头声明,配合 std::mutex 使用

典型场景是保护共享数据读写。比如多个线程往同一个 std::vector 里 push:

std::mutex mtx;
std::vector<int> data;
<p>void thread_func() {
// 加锁范围仅限于访问 data 的这几行
std::lock_guard<std::mutex> guard(mtx);
data.push_back(42);
// guard 离开作用域,自动 unlock()
}

注意:
- guard 必须声明在需要保护的代码之前,且作用域要严格包裹临界区
- 不要手动调用 guard.unlock():它没这个接口,也不该有
- 如果临界区很长或包含可能 throw 的操作,lock_guard 依然安全

和 unique_lock 对比:什么时候不该用 lock_guard

lock_guard 是最轻量、最严格的自动锁,但灵活性差。遇到以下情况,就得换 std::unique_lock:

  • 需要延迟加锁(构造时不锁,后面再 lock())
  • 需要手动控制解锁时机(比如先 unlock 再做耗时 IO,避免阻塞其他线程)
  • 要和条件变量 std::condition_variable 配合使用(wait() 要求传入 unique_lock)
  • 要转移锁的所有权(比如放进 std::move 返回值中)

lock_guard 没有 unlock()、try_lock()、release() 这些方法,也没提供底层 mutex* 访问接口——它就是为“进作用域即锁、出作用域即放”这个单一语义设计的。

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

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

容易忽略的细节:类型必须匹配,且 mutex 不能是临时对象

lock_guard 模板参数类型必须和传入的互斥量类型完全一致。常见错误:

std::recursive_mutex rm;
std::lock_guard<std::mutex> guard(rm); // ❌ 编译失败:类型不匹配

正确写法是:

std::lock_guard<std::recursive_mutex> guard(rm); // ✅

另一个坑是传入临时 mutex:

std::lock_guard<std::mutex> guard(std::mutex{}); // ❌ 构造完就销毁 mutex,guard 锁的是已析构对象

所有 mutex 实例必须是静态、全局、类成员或栈上持久存在的对象。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

更多
go语言goto的用法
go语言goto的用法

本专题整合了go语言goto的用法,阅读专题下面的文章了解更多详细内容。

3077

2025.09.05

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

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

3208

2023.10.19

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

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

5209

2025.10.17

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

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

3869

2025.12.29

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

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

486

2026.01.19

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

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

6487

2023.07.18

堆和栈区别
堆和栈区别

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

2708

2023.08.10

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

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

6487

2023.07.18

Tailwind CSS 如何制作导航栏和卡片
Tailwind CSS 如何制作导航栏和卡片

用 Tailwind CSS 制作导航栏和卡片,可先搭建语义化结构,再组合 Flex、Grid、间距、圆角与阴影类。这里整理横向导航、移动端菜单、卡片网格及悬停效果的相关文章,帮助你把常见页面组件做得清晰且适配不同屏幕。

0

2026.11.03

热门下载

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

精品课程

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn