c++ std::unique_lcock 详解

std::unique_lock  C++ 标准库中的一个类,用于管理对互斥锁(std::mutex 或其派生类)的锁定和解锁。它提供了比 std::lock_guard 更灵活的控制,允许在需要时延迟锁定、提前解锁以及递归锁定等。

主要特性

  1. 延迟锁定:std::unique_lock 可以在创建时不立即锁定互斥锁,而是在稍后的时间点调用 lock() 或 try_lock() 方法来锁定。
  2. 提前解锁:通过调用 unlock() 方法,可以在不销毁 std::unique_lock 对象的情况下解锁互斥锁。这允许在锁定期间执行不需要互斥锁的操作。
  3. 所有权转移:std::unique_lock 对象可以通过移动语义(使用 std::move)来转移其所有权,从而在不释放锁的情况下将锁传递给另一个 std::unique_lock 对象。
  4. 递归锁定:如果互斥锁是可递归的(即 std::recursive_mutex),则 std::unique_lock 可以多次锁定同一个互斥锁,而不会产生死锁。
  5. 条件变量:std::unique_lock 通常与 std::condition_variable 一起使用,因为 std::condition_variable 的 wait() 方法需要一个 std::unique_lock 参数来自动解锁和重新锁定互斥锁。

使用方法

  1. 创建和锁定

std::mutex mtx;

std::unique_lock<std::mutex> lck(mtx); // 立即锁定 mtx

或者延迟锁定:

std::unique_lock<std::mutex> lck(mtx, std::defer_lock); // 不立即锁定

lck.lock(); // 稍后锁定

  1. 提前解锁

lck.unlock(); // 解锁 mtx

注意,在解锁后重新使用 lck 前,必须确保没有其他线程已经锁定了 mtx,否则可能会导致未定义的行为。

  1. 所有权转移

std::unique_lock<std::mutex> lck1(mtx);

std::unique_lock<std::mutex> lck2 = std::move(lck1); // lck1 不再拥有锁,lck2 现在拥有锁

  1. 与条件变量一起使用

std::condition_variable cv;

std::mutex mtx;

std::unique_lock<std::mutex> lck(mtx);

cv.wait(lck, []{ /* 条件检查 */ }); // 在等待期间,lck 会自动解锁和重新锁定 mtx

  1. 递归锁定(如果使用的是 std::recursive_mutex):

std::recursive_mutex rmtx;

std::unique_lock<std::recursive_mutex> rlck(rmtx);

rlck.lock(); // 可以多次锁定同一个 rmtx,不会产生死锁

注意事项

  • 不要混合使用 std::lock_guard 和 std::unique_lock 来管理同一个互斥锁,因为这可能会导致未定义的行为。
  • 在使用 std::unique_lock 时,要特别小心避免在解锁后重新使用它之前让其他线程锁定相同的互斥锁。
  • std::unique_lock 在其析构函数中会自动解锁互斥锁(除非它已经处于未锁定状态)。因此,通常不需要显式调用 unlock(),除非有特定的需求。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值