unique_lock详解
-
unique_lock取代lock_guard
unique_lock是一个类模板,其将一个互斥量与自身绑定,可以完全取代lock_guard
unique_lock<mutex> myguard(mymutex)等价于lock_guard<mutex> myguard(mymutex)
相比于lock_guard,unique_lock更加灵活,但在效率上差一点,内存占用上多一点。 -
unique_lock的第二个参数
adopt_lock
示例:unique_lock<mutex> myguard(mymutex, adopt_lock)
作用:表明互斥量mymutex已经被lock()上了,不会在unique_lock的构造函数中调用mymutex.lock(),因此在使用这个参数前必须将互斥量上锁。
try_to_lock
示例:unique_lock<mutex> myguard(mymutex, try_to_lock)
作用:尝试去锁上互斥量mymutex,如果没有锁上也不会在此处等待,而是立刻返回,因此在使用前不能将互斥量上锁。void inMsgRecvQueue() { for (int i = 0; i < 10; ++i) { cout << "inMessageQueue执行,插入一个元素" << i << endl; unique_lock<mutex> myguard(mymutex, try_to_lock); //使用成员函数owns_lock()来 判断是否上锁成功 if (myguard.owns_lock()){ msgRecvQueue.push_back(i); } else { cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl; } } }defer_lock
示例:unique_lock<mutex> myguard(mymutex, defer_lock)
作用:初始化了一个没有加锁的互斥量,可以配合其成员函数灵活使用,因此在使用前不能将互斥量上锁。void inMsgRecvQueue() { for (int i = 0; i < 10; ++i) { cout << "inMessageQueue执行,插入一个元素" << i << endl; unique_lock<mutex> myguard(mymutex1, defer_lock); myguard.lock(); //开始处理共享数据1 myguard.unlock(); myguard.lock(); //开始处理共享数据2 if (myguard1.owns_lock()){ msgRecvQueue.push_back(i); } else { cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl; } } }注意:如果在最后面给互斥量解锁了,在函数结束时,
myguard调用析构函数将不会执行mymutex.unlock() -
unique_lock的成员函数
lock():给其绑定的互斥量上锁
unlock():给其绑定的互斥量解锁
try_lock():尝试给互斥量上锁,如果成功,返回True,否则返回False,此函数不会造成阻塞void inMsgRecvQueue() { for (int i = 0; i < 10; ++i) { cout << "inMessageQueue执行,插入一个元素" << i << endl; unique_lock<mutex> myguard(mymutex, defer_lock); if (myguard.try_lock()){ msgRecvQueue.push_back(i); } else { cout << "执行inMsgRecvQueue(),没拿到锁,只能干点别的" << endl; } } }release():
返回它所绑定的mutex对象指针,并释放所有权,此后mymutex与myguard不再有关
如果原mutex处于加锁状态,有责任在处理完后进行mutex.unlock()操作void inMsgRecvQueue() { for (int i = 0; i < 10; ++i) { cout << "inMessageQueue执行,插入一个元素" << i << endl; unique_lock<mutex> myguard(mymutex); mutex* p = myguard.release(); msgRecvQueue.push_back(i); p->unlock(); } } -
unique_lock所有权的传递
unique_lock<mutex> myguard(mymutex, defer_lock)
当一个unique_lock与一个mutex绑定后,unique_lock就拥有了mutex的所有权
所有权可以转移move()但不能复制,类似与智能指针unique_ptrvoid inMsgRecvQueue() { for (int i = 0; i < 10; ++i) { cout << "inMessageQueue执行,插入一个元素" << i << endl; unique_lock<mutex> myguard1(mymutex); unique_lock<mutex> myguard2(move(myguard1)); msgRecvQueue.push_back(i); } }转移后
myguard2继承了myguard1所绑定的mutex,myguard1什么都不绑定。









