std::unique_lock

std::unique_lock 是 C++11 标准库中的一个类,提供了一种灵活的方式来管理互斥量(mutex)。
它比 std::lock_guard 更加灵活,允许在不同的作用域和不同的锁定策略之间进行选择。以下是对 unique_lock 的详细解释,包括其用途、使用方法和优点。

1. 定义

  • std::unique_lock 是一种 RAII(资源获取即初始化)风格的锁,它在构造时锁定给定的互斥量,并在析构时自动解锁。这确保了在离开作用域时,锁会被自动释放,从而避免死锁。

2. 用途

  • 用于保护共享资源,确保在多线程环境中,只有一个线程能够访问该资源。
  • 适合需要在多个地方手动控制锁定与解锁的场景,例如在条件变量中使用。
  • 可以与 std::condition_variable 一起使用,以便在等待条件变量时自动管理锁。

3. 如何使用

以下是使用 std::unique_lock 的基本步骤和示例代码:

示例代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cond_var;
int shared_data = 0;

void producer() {
    std::unique_lock<std::mutex> lock(mtx);  // 锁定互斥量
    shared_data = 42;                         // 修改共享数据
    std::cout << "Produced: " << shared_data << std::endl;
    cond_var.notify_one();                    // 通知消费者
} // 离开作用域时自动解锁

void consumer() {
    std::unique_lock<std::mutex> lock(mtx);  // 锁定互斥量
    cond_var.wait(lock, [] { return shared_data != 0; }); // 等待条件变量
    std::cout << "Consumed: " << shared_data << std::endl;
} // 离开作用域时自动解锁

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);

    t1.join();
    t2.join();

    return 0;
}

4. 为什么要用它

  • 灵活性:与 std::lock_guard 相比,std::unique_lock 提供了更多的灵活性,支持以下功能:

    • 可以在构造时选择是否锁定互斥量。
    • 支持手动锁定和解锁:可以在需要时调用 lock()unlock() 方法。
    • 支持条件变量的等待:在等待条件变量时,可以传入 unique_lock,并在条件满足时自动解锁和重新锁定。
  • 避免死锁:由于 std::unique_lock 的 RAII 特性,确保在作用域结束时自动解锁,降低了因忘记解锁而引起死锁的风险。

  • 可以延迟锁定:你可以在构造 unique_lock 时不锁定互斥量,并在后面需要时再手动锁定。

5. 总结

  • std::unique_lock 是一种灵活且安全的互斥量管理方式,适合在复杂的多线程环境中使用。
    它不仅简化了锁的管理,还减少了编程错误的可能性,尤其是在涉及条件变量和复杂的锁定策略时。
posted @ 2024-10-06 18:06  牛马chen  阅读(216)  评论(0编辑  收藏  举报