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

风芳小哥_2192

风芳小哥_2192

2026-02-05

448人浏览

原创

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

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

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

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

所以你不能:
- new lock_guard(m):堆分配对象不会自动析构
- return lock_guard(m):返回临时对象会触发移动/拷贝,而 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<:mutex> guard(mtx);
data.push_back(42);
// guard 离开作用域,自动 unlock()
}</:mutex></p></int>

注意:
- 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* 访问接口——它就是为“进作用域即锁、出作用域即放”这个单一语义设计的。

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

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

C++14
C++14

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

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

正确写法是:

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

另一个坑是传入临时 mutex:

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

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

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

相关文章

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

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

下载

相关标签:

c++ 作用域

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

相关专题

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

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

2025.09.05

3077

5

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

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

2023.10.19

3208

3

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

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

2025.10.17

5229

12

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

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

2025.12.29

3869

9

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

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

2026.01.19

486

15

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

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

2023.07.18

6487

5

堆和栈区别
堆和栈区别

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

2023.08.10

2708

6

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

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

2023.07.18

6487

5

堆和栈区别
堆和栈区别

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

2023.08.10

2708

6

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程