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 取决于你对锁的管理需求。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在给定的代码示例中,`std::mutex`,`std::unique_lock`和`std::lock_guard`是C++中用于实现线程同步的标准库类。它们可以用于保护共享资源,以确保在多个线程同时访问该资源时不会出现竞争条件。 `std::mutex`是一个互斥体,用于实现互斥锁。它可以在需要时锁定共享资源,并在不再需要访问时解锁它。在给定的代码示例中,`std::mutex mt`是一个互斥体对象。 `std::unique_lock`和`std::lock_guard`都是互斥锁的RAII(资源获取即初始化)封装类。它们提供了一种便捷的方式来锁定和解锁互斥锁。不同之处在于,`std::unique_lock`提供了更多的灵活性,可以在运行时选择锁定和解锁的时机,而`std::lock_guard`在构造时锁定互斥锁,在析构时解锁互斥锁。在给定的代码示例中,`std::lock_guard`和`std::unique_lock`都用于在执行特定代码块时锁定互斥锁,并在代码块结束时解锁它们。 在混用`std::mutex`,`std::unique_lock`和`std::lock_guard`时,可以根据具体的需求选择合适的组合。例如,如果您需要在代码块中灵活地锁定和解锁互斥锁,可以使用`std::unique_lock`。如果您只需要在代码块中锁定和解锁互斥锁,并且不需要灵活性,可以使用`std::lock_guard`。这些类可以根据需要混合使用,以提供更具表达力和适应性的线程同步代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++11多线程编程——lock_guardunique_lock](https://blog.csdn.net/m0_47313541/article/details/130480617)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值