C++11并发与多线程(六、unique_lock详解)

一、unique_lock 取代 lock_guard

  1. unique_lock是个类模板,比lock_guard 相对更灵活

二、 unique_lock**的第二个参数

  1. std::adopt_lock: 是个结构体对象,起一个标记作用:表示这个互斥量已经lock(),不需要在std::lock_guard构造函数里面对对象进行再次lock()了(用这个adopt_lock前提是你自己需要先去lock
    mutex1.lock();
    std::unique_lock<std::mutex> guard1(mutex1, std::adopt_lock);
    
  2. std::try_to_lock : 会尝试用mutex的lock()去锁这个mutex,但如果没有锁成功,我也会立即返回并不会阻塞在那里(用这个try_to_lock前提是你自己不能先去lock
    std::unique_lock<std::mutex> guard1(mutex1, std::try_to_lock);
    if (guard1.owns_lock())	//判断是否拿到了锁,拿到了锁,拿到了锁才能操作共享数据
    {
    	cout << "插入一个元素 : " << i << endl;
    	m_list.push_back(i);
    }
    else
    {
    	cout << "我还没拿到锁呢" << endl;
    }
    
  3. std::defer_lock: 初始化了一个没加锁的mutex(用这个try_to_lock前提是你自己不能先去lock

三、unique_lock的成员函数

  1. lock()函数 : 加锁 不需要自己unlock()
    unique_lock<mutex> unique(mutex1, std::defer_lock);	//没有加锁的mutex
    unique.lock();		//不用自己unlock()
    m_list.push_back(i);
    
  2. unlock()函数 :解锁
    unique_lock<mutex> unique(mutex1, std::defer_lock);	//没有加锁的mutex
    unique.lock();		//不用自己unlock()
    //.....因为有一些非共享代码需要处理 所以临时需要先解锁
    unique.unlock();
    //又处理一些共享代码 可以又临时把锁加上
    unique.lock();
    m_list.push_back(i);
    
  3. try_lock()函数 :尝试给互斥量加锁,如果拿不到锁,则返回false ,如果拿到了就返回true
    unique_lock<mutex> unique(mutex1, std::defer_lock);	//没有加锁的mutex
    if (unique.try_lock() == true)
    {
    	m_list.push_back(i);
    }
    else
    {
    	cout << "我还没拿到锁呢" << endl;
    }
    
  4. release()函数 : 返回它所管理的原始mutex对象指针,并释放所有权(也就是说,这个unique_lock和mutex不再有关系);如果原来mutex对象处于加锁状态,你有责任接管过来并负责解锁
    unique_lock<mutex> unique(mutex1);	
    std::mutex *ptr =  unique.release();	//现在有责任自己解锁mutex
    m_list.push_back(i);
    ptr->unlock();	//自己负责 unlock();
    

    锁的粒度:锁住代码的多少,一般用粗细来描述,粒度越细,代码执行效率越高,相反越低

四、unique_lock所有权的传递

std::unique_lock<std::mutex> unique(mutex1);	//unique拥有mutex1的所有权
//unique可以把自己对mutex(mutex1)的所有权转移给其他unique_lock对象,可以转移但是不能复制
unique_lock<mutex> unique(mutex1);	
unique_lock<mutex> unique1(unique);		//错误写法,非法,不能复制
unique_lock<mutex> unique1(std::move(unique));	//正确写法,合法 //此时 unique 为空 

也可以这样传递:

std::unique_lock<std::mutex> GetUnique_Lock()
{
	std::unique_lock<std::mutex> unique(mutex1);
	return unique;	//返回局部对象
}
unique_lock<mutex> unique1 = GetUnique_Lock();	

你可能感兴趣的:(C++STL,多线程,c++11,指针,并发编程)