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 resourcereturn 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()
函数进行递归加锁。