unique_lock源码
时间: 2023-10-30 21:06:46 浏览: 42
unique_lock 是 C++11 中新增的一种互斥量封装类,用于更方便地管理互斥量的加锁和解锁。它的源码实现在 <mutex> 头文件中。
unique_lock 是一个模板类,定义如下:
```c++
template<class Mutex>
class unique_lock {
public:
// 构造函数
explicit unique_lock(Mutex& m);
unique_lock(Mutex& m, defer_lock_t);
unique_lock(Mutex& m, try_to_lock_t);
unique_lock(Mutex& m, adopt_lock_t);
template<class Clock, class Duration>
unique_lock(Mutex& m, const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
unique_lock(Mutex& m, const chrono::duration<Rep, Period>& rel_time);
// 析构函数
~unique_lock();
// 成员函数
void lock();
bool try_lock();
void unlock();
void swap(unique_lock& other) noexcept;
bool owns_lock() const noexcept;
explicit operator bool() const noexcept;
// 禁止拷贝和赋值
unique_lock(const unique_lock&) = delete;
unique_lock& operator=(const unique_lock&) = delete;
// 友元函数
template<class Mutex2>
friend class unique_lock;
};
```
unique_lock 有多个构造函数,用于不同的场景:默认构造函数会创建一个未关联互斥量的 unique_lock 对象;explicit unique_lock(Mutex& m) 构造函数会创建一个关联了互斥量 m 的 unique_lock 对象,并立即对互斥量进行加锁;unique_lock(Mutex& m, try_to_lock_t) 构造函数会尝试对互斥量 m 进行加锁,如果加锁失败则不会阻塞线程,而是立即返回 false;unique_lock(Mutex& m, adopt_lock_t) 构造函数会创建一个 unique_lock 对象,但是假设调用者已经对互斥量 m 进行加锁,因此 unique_lock 对象不会再对互斥量进行加锁,而是认为互斥量已经被加锁了;unique_lock(Mutex& m, const chrono::time_point<Clock, Duration>& abs_time) 和 unique_lock(Mutex& m, const chrono::duration<Rep, Period>& rel_time) 构造函数会尝试在指定的时间内对互斥量进行加锁。
unique_lock 的成员函数包括:
- lock():对关联的互斥量进行加锁。
- try_lock():尝试对关联的互斥量进行加锁,如果加锁成功则返回 true,否则返回 false。
- unlock():对关联的互斥量进行解锁。
- swap(unique_lock& other):交换两个 unique_lock 对象的状态。
- owns_lock():返回当前 unique_lock 对象是否拥有互斥量的所有权。
- operator bool():返回当前 unique_lock 对象是否拥有互斥量的所有权。
此外,unique_lock 还有一个特殊的成员函数,用于将 unique_lock 对象转换为 lock_guard 对象:
```c++
template<class Mutex>
std::lock_guard<Mutex> unique_lock<Mutex>::release() noexcept;
```
该函数会将当前 unique_lock 对象所拥有的互斥量的所有权转移到一个新的 lock_guard 对象中,并将当前 unique_lock 对象重置为未关联任何互斥量的状态。
unique_lock 的实现方式与 lock_guard 类似,都是通过 RAII 技术来实现对互斥量的加锁和解锁。不同的是,unique_lock 提供了更加灵活的构造函数和成员函数,可以在更多的场景下使用。此外,unique_lock 还支持线程间传递所有权,这是 lock_guard 所不具备的功能。