unique_lock
是一个类模板,其将一个互斥量与自身绑定,可以完全取代lock_guard
unique_lock
等价于lock_guard
相比于lock_guard
,unique_lock
更加灵活,但在效率上差一点,内存占用上多一点。
adopt_lock
示例:unique_lock
作用:表明互斥量mymutex
已经被lock()
上了,不会在unique_lock
的构造函数中调用mymutex.lock()
,因此在使用这个参数前必须将互斥量上锁。
try_to_lock
示例:unique_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
作用:初始化了一个没有加锁的互斥量,可以配合其成员函数灵活使用,因此在使用前不能将互斥量上锁。
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()
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
绑定后,unique_lock
就拥有了mutex
的所有权
所有权可以转移move()
但不能复制,类似与智能指针unique_ptr
void 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
什么都不绑定。