std::lock_guard 是 std::mutex 的 raii 封装,构造时加锁、析构时自动解锁;必须为栈对象,不可复制或移动,不支持手动解锁,类型需显式指定模板参数。

lock_guard 构造时就加锁,析构时自动释放
它不是“实现”互斥锁释放逻辑的工具,而是 std::mutex 的 RAII 封装:构造函数调用 mtx.lock(),析构函数调用 mtx.unlock()。只要对象生命周期结束(比如离开作用域),解锁就必然发生,不依赖 return 位置或异常路径。
常见错误是手动调用 unlock() 或试图重复 lock —— lock_guard 不提供这些接口,强行绕过会导致编译失败,反而是保护机制。
必须用栈对象,不能 new 出来
RAII 依赖对象在作用域末尾被销毁。如果写成 auto* lg = new std::lock_guard<:mutex>(mtx);</:mutex>,析构不会自动触发,锁永远不释放,直接死锁。
正确写法只有这一种形式:
std::mutex mtx;
{
std::lock_guard<:mutex> lg(mtx); // ✅ 栈对象,作用域结束自动 unlock
// ... 临界区
} // ← 这里 lg 被析构,mtx 解锁</:mutex>
不能转移、不能复制,避免意外延长锁持有时间
lock_guard 的拷贝构造和赋值运算符都被 = delete 了。这是故意设计:防止把锁“传出去”导致你误以为锁已释放,其实还在某个临时对象里挂着。
典型误用场景:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 返回
lock_guard从函数 —— 编译报错:use of deleted function - 存进
std::vector<:lock_guard>></:lock_guard>—— 同样编译失败 - 用
std::move(lg)试图转移 —— 无效,移动构造也被删了
它的存在意义就是“短命 + 确定性”,多一秒都不该活。
和 unique_lock 的关键区别在哪
如果你需要延迟加锁、手动解锁、或转移锁所有权,lock_guard 不行,得换 std::unique_lock。但代价是额外内存开销(内部有布尔标志位)和轻微性能损失。
简单对比:
-
lock_guard:轻量、不可变、仅构造/析构控制锁 —— 适合绝大多数“进作用域就锁、出就放”的场景 -
unique_lock:支持unlock()、try_lock()、可移动、可 default 构造(不立即锁)—— 适合复杂同步逻辑
别为了“以后可能要扩展”提前用 unique_lock,多数时候只是白占空间、误导读者以为这里有特殊控制流。
最易被忽略的一点:lock_guard 的类型必须显式写出模板参数,不能靠 auto 推导 —— 因为构造函数是 explicit 的,auto lg = std::lock_guard(mtx) 会编译失败。必须写全 std::lock_guard<:mutex></:mutex>。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










