目录
std::unique_lock代替std::lock_guard
std::unique_lock代替std::lock_guard
std::unique_lock的作用与std::lock_guard基本相同,也是用于管理对互斥量的锁定与解锁,但更加的灵活。std::unique_lock支持std::lock_guard的所用操作,用法也基本相同,同时还支持一些其他的操作,包括延迟锁定、条件等待、尝试锁定、锁定时长、使用权转移、手动解锁。
unique_lock的第二个参数
std::adopt_lock
表示互斥量已将lock了,线程已经获得了互斥量的所有权,不需要再使用unique_lock获取锁。这个功能lock_guard也可以使用,与unique_lock中的含义相同。
使用adopt_lock需要确保线程已经获取了锁。
std::try_to_lock
当使用了std::try_to_lock后,如果没有获得锁,std::unique_lock并不会阻塞当前的线程,可以去执行一些其他的操作,等一段时间后再尝试获取锁,或者返回通知我们获取锁失败,然后继续执行代码。
但使用std::try_to_lock()时,要注意确保本线程还未被获取锁。否则使用std::try_to_lock()再次尝试上锁将导致出错。
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;
mutex mut;
list<int> mydata;
void newthread()
{
unique_lock<std::mutex> myuq_lock(mut, try_to_lock);
if (myuq_lock.owns_lock())
{
//成功获得锁
mydata.push_back(6);
}
else
{
cout << "获得锁失败" << endl; //失败获得锁
}
}
int main()
{
thread mythread1(newthread);
thread mythread2(newthread);
mythread1.join();
mythread2.join();
}
std::defer_lock
std::defer_lock的作用是延迟锁的获取,表示unique_lock初始时不要尝试获取锁,而是当调用lock或者try_lock成员函数时再获取锁。使用std::defer_lock同样需要确保线程还未获得锁头。
#include<iostream>
#include<thread>
#include<mutex>
#include<list>
using namespace std;
mutex mut;
list<int> mydata;
void newthread()
{
unique_lock<std::mutex> myuq_lock(mut,defer_lock);
myuq_lock.lock();
mydata.push_back(6);
}
int main()
{
thread mythread1(newthread);
thread mythread2(newthread);
mythread1.join();
mythread2.join();
}
unique_lock的成员函数
lock()和unlock()
unique_lock对象也可以显式的调用lock()和unlock()去获取和释放锁。
try_lock()
尝试获取锁,如果获取成功则返回true,失败则返回false。一般与defer_lock配合使用。
release()
释放std::unique对互斥量的所用权,并返回管理的mutex的对象指针。使用release()后,需要手动的调用互斥量的unlock()成员函数释放锁。
unique_lock所有权的传递
与unique_ptr相似,unique_lock对mutex对象的所用权可以转移,但不可以复制。同一时间,mutex的所有权仅能被一个unique_lock拥有。可以使用std::move()转移unique_lock的所有权。