C++并发与多线程编程--unique_lock


1、unique_lock概念

unique_lock是一个类模板,工作中一般使用lock_guard(推荐使用)

unique_lock比lock_guard灵活,但效率差一些,内存消耗也多一些。一般用法:

std::mutex my_mutex;
//...............
std::unique_lock(std::mutex) sbguard(my_mutex);


2、unique_lock参数

(1)std::adpot_lock
前提:在此之前要先加lock。
表示互斥量已经被lock,无需再lock(如果使用这个参数,而互斥量在此之前没有被lock,那么会报异常)。

std::mutex my_mutex;
//...............
my_mutex.lock();  //必须要先lock,否则报异常
std::unique_lock(std::mutex) sbguard(my_mutex, std::adpot_lock);


(2)std::try_to_lock
前提:不能在此之前加锁,否则卡死。
尝试加锁,如果无法锁住,则做其他事情,不会一直等待其他线程释放锁。

std::mutex my_mutex;
//..............
std::unique_lock(std::mutex) sbguard(my_mutex, std::try_to_lock);
if(sbguard.owns_lock())
{
    //表示拿到锁
}
else
{
    //拿不到锁,做其他事情
}

//延迟函数
std::chrono::milliseconds dura(2000); // 2秒
std::this_thread::sleep_for(dura); //sleep2秒


(3)std::defer_lock
前提:不能在此之前加锁,否则卡死。
并没给mutex加锁,而是初始化了一个没有加锁的mutex。

std::mutex my_mutex;
//..............
std::unique_lock(std::mutex) sbguard(my_mutex, std::defer_lock);
sbguard.lock();


3、unique_lock成员变量

std::mutex my_mutex;
//..............
std::unique_lock(std::mutex) sbguard(my_mutex, std::defer_lock);

(1)lock()–加锁:sbguard.lock();

(2)unlock()–解锁:sbguard.unlock();

为什么自动可以unlock,还需要unlock( ) ?
lock的代码越少,效率越高。把锁住代码的多少,也成为锁的粒度,粒度一般用粗细表示。
一段代码中,有共享数据,也有非共享数据,在共享数据可以lock,到非共享数据的时候可以unlock。

(3)try_lock()–尝试加锁

sbguard.try_lock( );   //锁住返回true,否则返回false  ,拿到锁做一些共享代码,拿不到做些其他事情。

(4)release()– 返回它所管理的mutex对象指针,并释放所有权,unique_lock与mutex不再有关系

std::unique_lock(std::mutex) sbguard(my_mutex, std::defer_lock);
std::mutex *ptr = my_mutex.release();
//.................
ptr->unlock();    //需要负责unlock


4、unique_lock所有权转移mutex

std::mutex my_mutex;
//..............
std::unique_lock(std::mutex) sbguard(my_mutex);

sbguard可以把自己对my_mutex的所有权转移给其他的unique_lock对象。
可以转移,但是不能复制。

方式1:

std::mutex my_mutex;
//..............
std::unique_lock(std::mutex) sbguard1(my_mutex);
std::unique_lock(std::mutex) sbguard2(std::move(sbguard1));

方式2:

std::unique_lock<std::mutex> rtn_unique_lock()
{
    std::unique_lock<std::mutex> tmpguard(my_mutex);

	//从函数返回一个局部的unique_lock是可以的
	//返回这种局部对象unique_lock会导致系统生成临时unique_lock对象,并调用unique_lock的移动构造函数。
    return tmpguard;                        
}

//............
std::unique_lock<std::mutex> guard1 = rtn_unique_lock();

你可能感兴趣的:(C++,C++,多线程,unique_lock)