六、unique_lock
一、unique_lock取代lock_guard
是个类模板,一般用lock_guard,unique_guard更灵活,效率差一点,内存占用多了一点。
二、unique_lock 的第二个参数
1、std::adopt_lock
就是个标记,表示位于第一个参数的互斥量已经lock了。(你必须先把这个互斥量lock,否则会报异常)
2、std::try_to_lock
正常情况下线程A锁住一个mutex,然后要求等待10秒,这个时候另一个线程B要锁这个mutex,但是由于线程A没有解锁这个mutex,那么线程B相当于也要等至少10秒钟,会卡在这里,等A解锁了这个mutex才能去拿这个锁。对于这种情况,unique_lock就能够灵活的处理。
unique_lock的try_to_lock参数会尝试用mutex的lock()去锁住这个mutex,但如果没有锁定成功,也会立即返回,并不会阻塞在那里。(前提是你自己不能先去lock)
void InMsgQue(){
for(int i=;i<;i++){
cout<<"InMsgQue执行,插入一个元素"<<i<<endl;
std::unique_lock<std::mutex> my_lock(my_mutex1,std::try_to_lock);
if(my_lock.owns_lock()){//判断是否拿到了锁
//拿到了锁。。。。。
}
else{
//没拿到锁的话要做的事情
}
MyQue.push_back(i);//假设i就是命令
//其他处理代码、、、、、、、
}
}
3、std::defer_lock
前期:不能自己先去lock
并没有给mutex加锁,初始化了一个没有加锁的mutex,这样就方便里调用一些unique_lock的一些成员函数。
void InMsgQue(){
for(int i=;i<;i++){
cout<<"InMsgQue执行,插入一个元素"<<i<<endl;
std::unique_lock<std::mutex> my_lock(my_mutex1,std::defer_lock);//没有枷锁的mutex,相当于将my_mutex1和my_lock绑定一起了
my_lock.lock();//不用自己unlock
if(my_lock.owns_lock()){//判断是否拿到了锁
//拿到了锁。。。。。
}
else{
//没拿到锁
}
MyQue.push_back(i);//假设i就是命令
//其他处理代码、、、、、、、
}
}
三、unique_lock成员函数
1、lock
2、unlock
配合defer_lock参数
unique_lock可以自己unlock了,为什么还要有unlock这个成员函数?
void InMsgQue(){
for(int i=;i<;i++){
cout<<"InMsgQue执行,插入一个元素"<<i<<endl;
std::unique_lock<std::mutex> my_lock(my_mutex1,std::defer_lock);//没有枷锁的mutex,相当于将my_mutex1和my_lock绑定一起了
my_lock.lock();//不用自己unlock
//有时候有一些非共享代码要去处理,所以先unlock
my_lock.unlock();
//接着处理一些共享代码
my_lock.lock();
//其他处理代码.......
//my_lock.unlock();//画蛇添足,unique_lock的析构函数会unlock,但是也不会出问题
}
为什么有时候需要unlock()?
因为lock锁住的代码越少,执行越快,整个程序运行效率就越高。
有人也把锁住的代码多少称为锁的粒度,粒度一般用粗细来秒速。
锁住的代码少,粒度细,执行效率高;
锁住的代码高,粒度粗,执行效率低;
要尽量选择合适的粒度,粒度太细,可能漏掉对共享数据的保护,粒度太粗,影响效率。
3、try_lock
配合defer_lock使用。
void InMsgQue(){
for(int i=;i<;i++){
cout<<"InMsgQue执行,插入一个元素"<<i<<endl;
std::unique_lock<std::mutex> my_lock(my_mutex1,std::defer_lock);//没有枷锁的mutex,相当于将my_mutex1和my_lock绑定一起了
if(my_lock.try_lock()==true){
//如果拿到锁了。。。。。
}
else{
//如果没拿到所
}
}
}
4、release
返回它管理的mutex对象指针,释放所有权,也就是这个unique_lock和mutex不再有关系。
和unlock不同的,不要混淆。
void InMsgQue(){
for(int i=;i<;i++){
std::unique_lock<std::mutex> my_lock(mutex1);
std::mutex *ptx = my_lock.release();//断开my_lock和mutex1的关系,所以你要自己解锁了
ptx->unlock();//自己负责mutex1的unlock
cout<<"InMsgQue执行,插入一个元素"<<i<<endl;
}
}
四、unique_lock所有权的传递
一个unique_lock要只和一个mutex绑定在一起,也就是一个unique_lock只管理一个mutex。
my_lock也就是拥有mutex1的所有权。
my_lock可以把自己对mutex1的所有权 是属于可以转移,不能复制。
unique_lock也可以作为函数定义时的返回类型的:
std::unique_lock<std::mutex> my_lock(){
std::unique_lock<std::mutex> temp_lock(mutex1);
return temp_lock;
}
std::unique_lock<std::mutex> new_lock = my_lock();
六、unique_lock的更多相关文章
- Android 12(S) 图形显示系统 - BufferQueue/BLASTBufferQueue之初识(六)
题外话 你有没有听见,心里有一声咆哮,那一声咆哮,它好像在说:我就是要从后面追上去! 写文章真的好痛苦,特别是自己对这方面的知识也一知半解就更加痛苦了.这已经是这个系列的第六篇了,很多次都想放弃了,但 ...
- 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...
- MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息
MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 【微信小程序开发•系列文章六】生命周期和路由
这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...
- 我的MYSQL学习心得(六) 函数
我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...
- 我的MYSQL学习心得(十六) 优化
我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- ASP.NET MVC Model绑定(六)
ASP.NET MVC Model绑定(六) 前言 前面的篇幅对于IValueProvider的使用做个基础的示例讲解,但是没并没有对 IValueProvider类型的实现做详细的介绍,然而MVC框 ...
随机推荐
- Linux学习篇(四)-Linux 文件管理命令详解
rootfs:根文件系统,Root FileSystem 的简称. Linux 文件命名规则 长度不超过255个字符. 不能使用/当文件名. 严格区分大小写. Linux 目录简介 / 根目录 /bo ...
- day24—JavaScript实现导航栏底部引线跟随移动
转行学开发,代码100天——2018-04-09 前面的学习笔记中记录过,利用:before和:after实现导航栏鼠标移动跟随效果,今天通过JavaScript代码实现同样的效果,以作对比. < ...
- Bootstrap 学习笔记11 按钮和折叠插件
复选框: <div class="btn-group" data-toggle="buttons"> <label for="se ...
- 阅读笔记02-读懂HTTPS及其背后的加密原理
1 为什么需要https 使用https的原因其实很简单,就是因为http的不安全. 当我们往服务器发送比较隐私的数据(比如说你的银行卡,身份证)时,如果使用http进行通信.那么安全性将得不到保障. ...
- 排序算法三:堆排序(Heapsort)
堆排序(Heapsort)是一种利用数据结构中的堆进行排序的算法,分为构建初始堆,减小堆的元素个数,调整堆共3步. (一)算法实现 protected void sort(int[] toSort) ...
- 《STL源码剖析》——第一、二、三章
第一章:概论: 换句话说,STL所实现的,是依据泛型思维架设起来的一个概念结构.这个以抽象概念(abstract concepts)为主体而非以实际类(classes)为主体的结构,形成了一个严谨的 ...
- mysql 数据库表结构对比语句
判断两个数据库互相不存在的表 select a.TABLE_SCHEMA,a.TABLE_NAME from information_schema.TABLES a where a.TABLE_SCH ...
- python学习三十七天函数的作用域查找顺序LEGB
python函数的作用域查找顺序LEGB,分别为 locals eclosing globals builtins .了解作用域的范围,可以更好的操作你想要的业务,分别介绍一下. 1,local ...
- 71.Edit Distance(编辑距离)
Level: Hard 题目描述: Given two words word1 and word2, find the minimum number of operations required ...
- JavaScript的变量作用域
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...