mutex,lock_guard ,unique_lock 的使用和区别

std::lock_guardstd::unique_lock 是 C++11 提供的两种用于管理互斥锁 (std::mutex) 的类,它们简化了锁的使用,确保锁的自动释放。

1. std::lock_guardstd::unique_lock 的区别

std::lock_guard
  • 功能std::lock_guard 是一种简单的锁管理器,用于在其生存期内锁定互斥锁,并在对象销毁时自动解锁。
  • 使用场景:适用于那些锁定后不需要解锁、重新锁定、延迟锁定或转移锁所有权的场景。
  • 特点
    • 不可转移std::lock_guard 不能转移所有权。
    • 不支持延迟锁定:一旦创建对象时必须立即锁定。
    • 不支持显式解锁:锁的解锁只能通过对象析构来完成。
  • 语法示例
std::mutex mtx;
{
    std::lock_guard<std::mutex> lock(mtx);
    // 在这个作用域内,互斥锁是锁定的
} // 作用域结束时,自动解锁
std::unique_lock
  • 功能std::unique_lock 是一个功能更为丰富的锁管理器,支持更多的锁管理操作,例如延迟锁定、显式解锁/重新锁定、锁的转移等。
  • 使用场景:适用于那些需要更灵活的锁管理操作的场景,例如需要延迟锁定、条件变量的等待等。
  • 特点
    • 可转移std::unique_lock 可以通过移动构造函数或移动赋值运算符转移锁的所有权。
    • 支持延迟锁定:可以在创建 std::unique_lock 对象时不立即锁定,而是在之后的某个时刻调用 lock() 函数来锁定。
    • 支持显式解锁/重新锁定:可以通过 unlock()lock() 方法手动解锁和重新锁定。
  • 语法示例
std::mutex mtx;
{
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟锁定
    // 在这个作用域内,互斥锁未锁定
    lock.lock(); // 手动锁定
    // 执行一些操作
    lock.unlock(); // 手动解锁
    // 其他操作
} // 作用域结束时,自动解锁(如果没有显式解锁)

2. std::lock_guardstd::unique_lockstd::mutex 的关系

  • std::mutex 是互斥锁的基本实现,它可以单独使用来显式地锁定和解锁资源。例如:
std::mutex mtx;
mtx.lock();
// 访问共享资源
mtx.unlock();

然而,这种方式容易出现问题,例如忘记解锁或在异常发生时导致死锁。

  • std::lock_guardstd::unique_lock 是基于 RAII(资源获取即初始化)原则的包装器类,它们在构造时锁定互斥锁,在析构时自动解锁,从而避免了忘记解锁的风险。这两者都依赖于 std::mutex,但提供了不同程度的封装和功能:
    • std::lock_guard 是一种简单且高效的方式,适合那些不需要复杂锁管理的场景。
    • std::unique_lock 提供了更灵活的控制,适合需要在锁的生命周期内执行复杂操作的场景。

总结

  • std::lock_guard:简单、高效,适用于不需要解锁、重新锁定或转移锁所有权的场景。
  • std::unique_lock:功能强大,支持延迟锁定、显式解锁/重新锁定和锁的转移,适合需要更灵活控制的场景。
  • std::mutex:是底层的互斥锁实现,可直接使用,但通常与 std::lock_guardstd::unique_lock 结合使用,以避免手动管理锁带来的复杂性。

选择 std::lock_guard 还是 std::unique_lock 取决于你对锁的管理需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值