std::unique_lock 是 C++ 标准库中提供的一个互斥量封装类,用于实现互斥访问和线程同步。它提供了更灵活的锁定和解锁机制,可以适应不同的场景和需求。
std::unique_lock 可以与 std::mutex 或其他可锁定的互斥量一起使用。以下是 std::unique_lock 的基本用法:
- 创建 std::mutex 对象或其他可锁定的互斥量。
std::mutex mutex;
- 使用 std::unique_lock 来锁定互斥量。
std::unique_lock<std::mutex> lock(mutex);
在构造函数中传入互斥量对象 mutex,它将自动对互斥量进行加锁操作。
- 执行受保护的代码块。
在 std::unique_lock 对象创建后,你可以在其范围内编写需要互斥访问的代码。
// 互斥访问的代码块
// ...
- 自动解锁。
std::unique_lock 对象 lock 在其范围结束后(即超出其作用域)将自动对互斥量进行解锁操作。这意味着你无需手动调用解锁函数。
下面是一个简单的示例,演示了如何使用 std::unique_lock 来保护共享资源的访问:
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mutex;
int sharedVariable = 0;
void increment() {
std::unique_lock<std::mutex> lock(mutex);
// 对共享资源进行互斥访问
++sharedVariable;
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "共享变量的值:" << sharedVariable << std::endl;
return 0;
}
在上述示例中,std::unique_lock
请注意,与 std::lock_guard 相比,std::unique_lock 提供了更多的灵活性,例如在锁定期间手动释放锁定、在构造函数中延迟锁定等。这使得 std::unique_lock 更适用于某些特定的情况,如条件变量和递归锁定等
本质区别
std::lock_guard 和 std::unique_lock 都是 C++ 标准库中用于管理互斥量的类,它们之间的本质区别如下:
所有权:
std::lock_guard:拥有互斥量的自动锁定权。一旦创建 std::lock_guard 对象,它将对互斥量进行锁定,并在其作用域结束时自动释放锁定。
std::unique_lock:拥有互斥量的手动锁定权。可以在构造函数中选择是否立即锁定互斥量,并可以在其作用域内手动控制锁定和解锁的时机。
灵活性:
std::lock_guard:提供了一种简单的、固定的锁定机制,不支持手动解锁。在 std::lock_guard 对象的作用域内,互斥量将一直保持锁定状态,直到作用域结束。
std::unique_lock:提供了更大的灵活性。可以在构造函数中选择是否立即锁定互斥量,还可以手动调用 lock() 和 unlock() 函数来控制锁定和解锁的时机。
条件变量的支持:
std::lock_guard:不支持与条件变量一起使用。由于 std::lock_guard 无法手动解锁,因此无法满足条件变量等待和通知的需求。
std::unique_lock:支持与条件变量一起使用。通过手动调用 unlock() 和 lock() 函数,可以在适当的时机解锁和重新锁定互斥量,以与条件变量协同工作。
总的来说,std::lock_guard 提供了一种简单的、固定的锁定机制,适用于大多数情况下简单的互斥访问。而 std::unique_lock 提供了更大的灵活性和更多的功能,例如手动控制锁定和解锁的时机,以及与条件变量的配合使用。因此,在需要更高级的互斥控制或与条件变量一起使用时,std::unique_lock 是更适合的选择。