一、unique_lock()
:
是一个类模板,可以取代lock_guard()
,相比起来前者更灵活,但效率较差,内存占用较多 ,一般工作中推荐使用lock_guard()。
二、unique_lock()
的第二个参数:
2.1 std::adopt_lock
:表示互斥量已经被lock,则在第二个参数添加此标志。(使用此参数则当前线程之前未使用lock()
)。
my_mutex1.lock();
std::lock_guard<std::mutex>myLockGuard(my_mutex1,std::adopt_lock);
2.2 std::try_to_lock()
:尝试给mute上lock(),如果没有锁定成功会立即返回,并不会产生阻塞。
//线程1:
std::unique_lock<std::mutex>myLockGuard(my_mutex1,std::try_to_lock);
if (myLockGuard.owns_lock())
{
//拿到锁
msgRecvQueue.push_back(i);
}
else
{
//未拿到锁
cout << "程序执行,未拿到锁..." << i << endl;
}
//线程2:
std::unique_lock<std::mutex>myLockGuard(my_mutex1);
//阻塞5s↓
std::chrono::milliseconds dura(200);
std::this_thread::sleep_for(dura);
if (!msgRecvQueue.empty())
{
//命令队列不为空
command = msgRecvQueue.front();//得到第一条命令
msgRecvQueue.pop_front();//移除刚取出命令
return true;
}
return false;
解释: 线程 2 拿到锁后陷入时长为dura的阻塞期,由于线程间独立运行,这时另一个线程不断通过try_to_lock()
尝试取锁,继续运行,这样可以防止因为锁的原因导致整个程序陷入等待状态,浪费大量CPU资源。
2.3 std::defer_lock
:初始化mutex但不lock()。搭配unique_lock
的成员函数使用。
- unique_lock成员函数:
1、lock()
:加锁
2、unlock()
:解锁
std::unique_lock<std::mutex>myLockGuard(my_mutex1,std::defer_lock);
myLockGuard.lock();
//处理共享代码...
myLockGuard.unlock();
//处理非共享代码...
myLockGuard.lock();
//处理共享代码...
msgRecvQueue.push_back(i);
- unique_lock成员函数:
1、try_lock()
:尝试加锁,不阻塞,返回值为bool。
std::unique_lock<std::mutex>myLockGuard(my_mutex1, std::defer_lock);
if (myLockGuard.try_lock() == true)
cout << "拿到锁" << endl;
else
cout << "未拿到锁" << endl;
- unique_lock成员函数:
1、release()
:返回所管理的mutex
对象指针,并释放所有权,即该unique_lock
与mutex
不再有关系。
2、 若该mutex处于加锁状态,记得自己进行解锁代码编写。
3、 返回值是一个mutex指针,通常创建mutex指针接受并进行手动解锁。
std::unique_lock<std::mutex>myLockGuard(my_mutex1);//已加锁
std::mutex* ptm = myLockGuard.release();//接触myLockGuard与my_mutex1的关系
msgRecvQueue.push_back(i);
ptm->unlock();//手动解锁
//my_mutex1.unlock();
三、unique_lock()
所有权的传递:
myLockGuard
拥有my_mutex1
的所有权:
std::unique_lock<std::mutex>myLockGuard(my_mutex1);
- 所有转移:
std::unique_lock<std::mutex>myLockGuard(my_mutex1);//已加锁
std::unique_lock<std::mutex>myLockGuard2(std::move(myLockGuard));
//所有权转移,后文不需自行解锁
- 函数返回unique_lock():
//成员函数:
std::unique_lock<std::mutex> retNnique()
{
std::unique_lock<std::mutex> my_guard(my_mutex1);
return my_guard;
//函数返回局部变量,编译器会自动调用移动构造函数
}
//线程:
std::unique_lock<std::mutex> myguardNow = A::retNnique();
**报错:释放函数 A::retNnique 中的锁定 this->my_mutex1 失败。**暂未解决