0

0

C++中的std::unique_lock比lock_guard强在哪里?(支持手动解锁与延迟加锁)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-12 14:59:53

|

964人浏览过

|

来源于php中文网

原创

std::unique_lock支持手动unlock、延迟构造、try-lock、move语义及配合condition_variable;std::lock_guard仅RAII自动加锁/解锁,不可干预、不可移动、无状态、更轻量。

c++中的std::unique_lock比lock_guard强在哪里?(支持手动解锁与延迟加锁)

std::unique_lock 支持手动 unlock(),lock_guard 完全不支持

这是最直接的差异:std::unique_lock 是可移动、可延迟、可手动控制的锁包装器;而 std::lock_guard 一旦构造就立即加锁,析构时自动释放,中间**无法干预**。如果你需要在临界区中途释放锁(比如等待条件变量、避免锁粒度太粗),只能用 std::unique_lock

常见错误现象:std::lock_guard 对象在作用域内“想提前放锁”却找不到 unlock() 方法,编译报错:error: 'class std::lock_guard<:mutex>' has no member named 'unlock'

  • 适用场景:调用 std::condition_variable::wait() 必须传入 std::unique_lock,因为 wait 内部会先 unlock,唤醒后再重新 lock
  • 手动解锁示例:
    std::mutex mtx;
    std::unique_lock lk(mtx);
    // ... 做一部分受保护操作
    lk.unlock(); // ✅ 合法且必要
    // ... 可能做非临界工作(如 IO、计算),不阻塞其他线程
    lk.lock();   // ✅ 可重新加锁
    // ... 继续临界区操作

std::unique_lock 支持延迟构造和 defer_lock 参数

std::lock_guard 构造即加锁,没有选择;std::unique_lock 可以用 std::defer_lock 标签初始化,不立刻持有锁——这让你能把加锁时机和锁对象生命周期解耦。

使用场景:实现 try-lock、多锁按序获取、或根据运行时条件决定是否加锁。

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

  • std::unique_lock<:mutex> lk(mtx, std::defer_lock); → 构造时不加锁
  • if (lk.try_lock()) { /* 成功进入临界区 */ } → 非阻塞尝试
  • std::unique_lock<:mutex> lk1(mtx1, std::defer_lock), lk2(mtx2, std::defer_lock); std::lock(lk1, lk2); → 避免死锁的批量加锁

性能与内存开销:unique_lock 更重,但代价通常可接受

std::lock_guard 是零开销抽象:它只是个 RAII 封装,不带状态,sizeof 通常等于一个指针(甚至更小);std::unique_lock 内部需记录是否已加锁、是否拥有锁等状态,有轻微内存和指令开销。

DALL·E 2
DALL·E 2

OpenAI基于GPT-3模型开发的AI绘图生成工具,可以根据自然语言的描述创建逼真的图像和艺术。

下载

不过,在绝大多数真实场景中,这点开销远小于锁本身的系统调用或缓存争用成本。别为了省几个字节放弃灵活性——除非你在超低延迟、高频短临界区的嵌入式实时系统里手写锁逻辑。

  • 典型 sizeof 差异(x64):sizeof(std::lock_guard<:mutex>) ≈ 1,sizeof(std::unique_lock<:mutex>) ≈ 16
  • 不要用 std::unique_lock 替代 std::lock_guard 仅仅为了“统一风格”——没 unlock / defer / transfer 需求时,std::lock_guard 更清晰、更轻量、意图更明确

unique_lock 支持 move 语义,lock_guard 不可拷贝也不可移动

std::unique_lock 可以 move(比如返回局部锁、传入 lambda 捕获),std::lock_guard 连 move 都被禁用(删除了移动构造函数)。这不是“强弱”问题,而是设计定位不同:前者是锁的“句柄”,后者是“作用域绑定锁”。

容易踩的坑:试图把 std::lock_guard 存进容器、作为函数返回值、或用在需要转移所有权的地方,编译直接失败。

  • 合法示例:
    std::unique_lock make_lock(std::mutex& m) {
        return std::unique_lock(m); // ✅ 可移动返回
    }
  • 非法示例:std::lock_guard<:mutex> lg(m); auto x = std::move(lg);编译错误

真正关键的不是“哪个更强”,而是“你是否需要 unlock、defer、try、move 或配合 condition_variable”。不需要时,std::lock_guard 更安全、更轻、意图更干净;一旦涉及任何动态锁控制,std::unique_lock 就不是可选项,而是唯一解。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

731

2023.08.22

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

271

2023.10.25

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

190

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

41

2026.01.05

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

463

2024.01.03

python中class的含义
python中class的含义

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

12

2025.12.06

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

8

2026.01.12

热门下载

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

精品课程

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

共18课时 | 4.4万人学习

Sass 教程
Sass 教程

共14课时 | 0.8万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号