c++中的mutex和lock_guard是什么_c++互斥锁使用方法【线程安全】

1次阅读

mutex 是 c++ 基础互斥锁,不支持递归和超时;lock_guard 是 RaiI 锁管理器,构造时加锁、析构时自动解锁,确保异常安全,不可复制或手动解锁。

c++中的mutex和lock_guard是什么_c++互斥锁使用方法【线程安全】

mutex 是 C++ 中用于保护共享资源的互斥量,而 lock_guard 是一个 RAII 风格的锁管理器,它在构造时自动加锁、析构时自动解锁,避免手动加锁/解锁遗漏导致的死锁或数据竞争。

mutex:最基础的互斥锁

std::mutex标准库提供的轻量级互斥锁,只能被一个线程持有。它不支持递归(同一线程重复 lock 会死锁),也不支持超时等待(如需这些功能,可用 std::recursive_mutexstd::timed_mutex)。

常用操作:

  • m.lock():阻塞式加锁,直到成功获取锁
  • m.unlock():释放锁(必须由当前持有锁的线程调用)
  • m.try_lock():非阻塞尝试加锁,返回 true 表示成功

lock_guard:自动管理锁的“守卫”

std::lock_guard 是最常用的锁包装器,基于 RAII 原则,确保锁的生命周期与作用域绑定——进作用域即加锁,出作用域即解锁(即使发生异常也安全)。

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

典型用法:

c++中的mutex和lock_guard是什么_c++互斥锁使用方法【线程安全】

MarketingBlocks AI

AI营销助理,快速创建所有的营销物料。

c++中的mutex和lock_guard是什么_c++互斥锁使用方法【线程安全】 27

查看详情 c++中的mutex和lock_guard是什么_c++互斥锁使用方法【线程安全】

std::mutex mtx; int shared_data = 0;  void safe_increment() {     std::lock_guard<std::mutex> guard(mtx); // 构造即 lock()     ++shared_data;                           // 访问临界区 } // guard 离开作用域,自动 unlock()

注意:lock_guard 不可复制、不可转移,只支持移动(但通常不需要移动);也不能手动调用 unlock() —— 它的设计就是“全托管”。

常见误用与注意事项

以下写法容易引发问题:

  • 手动调用 unlock() 后又让 lock_guard 析构 → 未定义行为
  • lock_guard 声明在函数开头,但临界区实际只在后面几行 → 锁持有时间过长,降低并发
  • 多个 mutex 加锁顺序不一致 → 可能导致死锁(建议始终按固定地址/变量名顺序加锁)
  • 在持有 mutex 期间调用可能阻塞或抛异常的函数(如 I/O、new)→ 延长锁持有时间,或异常导致提前退出但锁已释放(其实 lock_guard 仍安全,但逻辑可能出错)

更灵活的选择:unique_lock

如果需要延迟加锁、条件变量配合、或手动控制解锁时机,可用 std::unique_lock。它比 lock_guard 更重,但功能更全:

  • 支持默认构造(不关联 mutex)、defer_lock(构造时不加锁)
  • 可多次 lock/unlock,支持移动,能和 std::condition_variable 配合
  • 性能略低,非必要时优先用 lock_guard

基本上就这些。用好 mutex + lock_guard 就能解决大部分线程安全问题,关键在于:锁粒度要小、作用域要准、别跨函数传递裸 mutex。

text=ZqhQzanResources