std::lock_guard适用于简单场景,构造时加锁、析构时解锁,不支持手动控制;std::unique_lock更灵活,支持延迟加锁、手动加解锁、条件变量配合及所有权转移,适合复杂控制需求。多数情况下优先使用轻量的std::lock_guard。

在C++多线程编程中,std::lock_guard 和 std::unique_lock 都是用来管理互斥量(mutex)的RAII(资源获取即初始化)类,确保在作用域结束时自动释放锁。虽然功能相似,但它们在灵活性和使用场景上有明显区别。
1. 基本用途与设计目标
std::lock_guard 是最简单的锁管理工具,设计目标是提供最小化、高效且不可手动控制的锁机制。它在构造时加锁,析构时解锁,不支持中途释放或重新获取锁。
std::unique_lock 更加灵活,除了具备 lock_guard 的基本RAII功能外,还支持延迟加锁、手动加锁/解锁、条件变量配合使用以及锁所有权的转移。
2. 是否支持手动加锁与解锁
lock_guard 一旦创建就立即持有锁,直到对象销毁,期间无法主动释放锁。
立即学习“C++免费学习笔记(深入)”;
- lock_guard 不提供 lock() 或 unlock() 成员函数
- 适用于简单作用域内全程需要锁的场景
unique_lock 支持更细粒度的控制:
- 可以构造时不加锁:
std::unique_lock<std::mutex> ulk(mutex, std::defer_lock) - 可手动调用
ulk.lock()和ulk.unlock() - 适合锁只在部分代码段需要的场景
3. 与条件变量的配合使用
只有 std::unique_lock 可以作为参数传递给 std::condition_variable::wait()。
这是因为条件变量在等待时需要临时释放锁,并在被唤醒后重新获得锁,这种“释放-阻塞-重获”机制要求锁对象支持移动和手动控制,而 unique_lock 正好满足。

标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。
12
查看详情
示例:
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
// 等待线程
std::unique_lock<std::mutex> lk(mtx);
cv.wait(lk, []{ return ready; });
4. 性能与开销对比
由于 unique_lock 提供了更多功能,其内部状态比 lock_guard 更复杂,可能包含是否已加锁的标志位,因此有轻微的性能开销。
- lock_guard:轻量、高效,无额外状态
- unique_lock:稍重,但大多数场景下性能差异可忽略
建议:如果只是保护一段临界区且不需要延迟加锁或配合条件变量,优先使用 lock_guard。
5. 锁的所有权转移
unique_lock 支持移动语义,可以将锁的所有权从一个 unique_lock 对象转移到另一个,这在函数返回锁或封装锁逻辑时非常有用。
lock_guard 不可复制也不可移动,锁的作用域严格绑定在其声明的作用域内。
基本上就这些。选择哪个取决于需求:追求简洁安全用 lock_guard,需要灵活控制用 unique_lock。不复杂但容易忽略的是,很多开发者一开始都用 unique_lock,其实多数场景 lock_guard 更合适。
大家都在看:
EyeCare护眼工具如何优化屏幕刷新_EyeCare护眼工具屏幕刷新优化技巧指南
密室逃脱大师速成课:从道具扫描到机关破解
2025世界顶尖科学家论坛即将举办 郑湃深度解读人机协作、工业人工智能未来
外媒:希望每个游戏工作室都有属于自己的《宇宙机器人》






























暂无评论内容