std::unique_lock
是 C++11 中的一个互斥量封装类,用于提供更灵活和安全的互斥访问。与 std::lock_guard
不同,std::unique_lock
可以随时释放互斥锁,并且支持对互斥量进行延迟加锁和递归加锁。
在使用 std::unique_lock
时,需要先创建一个 std::mutex
对象,然后将其传递给 std::unique_lock
构造函数。例如:
#include <iostream>
#include <mutex>
int main() {
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
// accessing shared resource
return 0;
}
在上述代码中,mtx
是一个 std::mutex
对象,lock
是一个 std::unique_lock<std::mutex>
对象,用于对 mtx
进行加锁。在 std::unique_lock
对象被销毁时(例如离开函数作用域),它会自动释放对 mtx
的锁定,从而避免了忘记释放锁的问题。
此外,std::unique_lock
还提供了一些其他的功能,例如:
- 支持延迟加锁:可以在构造函数中将第二个参数设置为
std::defer_lock
,表示延迟到后续再加锁。 - 支持递归加锁:可以在构造函数中将第二个参数设置为
std::defer_lock
,然后调用lock()
函数多次来进行递归加锁。 - 支持条件变量:可以与
std::condition_variable
配合使用,以实现线程之间的同步。
例如,下面是一个示例程序,展示了如何使用 std::unique_lock
实现延迟加锁和递归加锁:
#include <iostream>
#include <mutex>
class Counter {
public:
Counter() : value_(0) {}
int Get() {
std::unique_lock<std::mutex> lock(mtx_);
return value_;
}
void Inc() {
std::unique_lock<std::mutex> lock(mtx_);
value_++;
}
void Add(int n) {
std::unique_lock<std::mutex> lock(mtx_, std::defer_lock);
for (int i = 0; i < n; i++) {
lock.lock();
value_++;
lock.unlock();
}
}
private:
int value_;
std::mutex mtx_;
};
int main() {
Counter counter;
counter.Inc();
std::cout << "Value: " << counter.Get() << std::endl;
counter.Add(3);
std::cout << "Value: " << counter.Get() << std::endl;
return 0;
}
在上述代码中,Counter
类使用 std::unique_lock
对 value_
成员变量进行保护。Inc()
函数和 Add()
函数都使用了 std::unique_lock
对象进行加锁,其中 Add()
函数在开始时使用了 std::defer_lock
延迟加锁,然后在循环内部使用了显式的 lock()
和 unlock()
函数进行递归加锁。