std::lock_gurad
是 C++11 中定义的模板类。定义如下:
template <class Mutex> class lock_guard;
lock_guard
对象通常用于管理某个锁(Lock)对象,因此与 Mutex RAII 相关,方便线程对互斥量上锁,即在某个 lock_guard
对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard
的生命周期结束之后,它所管理的锁对象会被解锁。
模板参数 Mutex 代表互斥量类型,例如 std::mutex 类型,它应该是一个基本的 BasicLockable 类型,标准库中定义几种基本的 BasicLockable 类型,分别是:
std::mutex
;std::recursive_mutex
;std::timed_mutex
;std::recursive_timed_mutex
(注:BasicLockable 类型的对象只需满足两种操作,lock 和 unlock,另外还有 Lockable 类型,在 BasicLockable 类型的基础上新增了 try_lock
操作,因此一个满足 Lockable 的对象应支持三种操作:lock,unlock 和 try_lock;最后还有一种 TimedLockable 对象,在 Lockable 类型的基础上又新增了 try_lock_for
和 try_lock_until
两种操作,因此一个满足 TimedLockable 的对象应支持五种操作:lock, unlock, try_lock, try_lock_for, try_lock_until)。
在 lock_guard
对象构造时,传入的 Mutex 对象(即它所管理的 Mutex 对象)会被当前线程锁住。在lock_guard
对象被析构时,它所管理的 Mutex 对象会自动解锁,由于不需要程序员手动调用 lock 和 unlock 对 Mutex 进行上锁和解锁操作,因此这也是最简单安全的上锁和解锁方式,尤其是在程序抛出异常后先前已被上锁的 Mutex 对象可以正确进行解锁操作,极大地简化了程序员编写与 Mutex 相关的异常处理代码。
值得注意的是,lock_guard
对象并不负责管理 Mutex 对象的生命周期,lock_guard
对象只是简化了 Mutex 对象的上锁和解锁操作,方便线程对互斥量上锁,即在某个 lock_guard
对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而 lock_guard
的生命周期结束之后,它所管理的锁对象会被解锁。
lock_guard
构造函数如下表所示:
locking (1) |
|
lock_guard 对象管理 Mutex 对象 m,并在构造时对 m 进行上锁(调用 m.lock())。 |
---|---|---|
adopting (2) |
|
lock_guard 对象管理 Mutex 对象 m,与 locking 初始化(1) 不同的是, Mutex 对象 m 已被当前线程锁住。 |
copy [deleted](3) |
|
lock_guard 对象的拷贝构造和移动构造(move construction)均被禁用,因此 lock_guard 对象不可被拷贝构造或移动构造。 |
adopt_mutex:“收养锁”- 先上锁,然后托管给lock_guard这个类,之后如果发生了异常阿也不需要没有解锁而产生死锁的现象。
void test() {//std::adopt_mutex的大妙处
test_mutex.lock();
lock_guard<std::mutex> lg(test_mutex, std::adopt_lock);
//在这里进行收养锁
cout << "hello test" << endl;
}
void test(int) {//test的配套练习
test_mutex.lock();
cout << "hello test(int)" << endl;
test_mutex.unlock();
}
标签:std,对象,lock,guard,mutex,Mutex From: https://www.cnblogs.com/love-9/p/18093283