六、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框 ...
随机推荐
- 【黑科技】花几分钟和孩子动手DIY,即可用手机完成全息影像!
http://baobao.sohu.com/20160902/n467277059.shtml [黑科技]花几分钟和孩子动手DIY,即可用手机完成全息影像! 杭州亲子圈2016-09-02 07:2 ...
- JAVA泛型知识(二)--> <? extends T>和<? super T>
<? extends T> 和 <? super T> 是Java泛型中的“通配符(Wildcards)” 和 “边界(Bounds)”的概念 <? extends T& ...
- php用什么软件编程
准备好好学习学习PHP了吗?那么你首先应该考虑用什么开发工具(IDE).市面上有很多这类工具,收费的有,免费的也有,选择起来并不轻松. 如果你说PHP编程用基础的文本编辑软件就可以了,比如用记事本.是 ...
- GitBook "How to be a programmer"
网址:https://www.gitbook.com/book/braydie/how-to-be-a-programmer/ 最近看了这本 GitBook,主要讲程序员应该掌握的技能和注意的问题,分 ...
- MySQL数据库忘记密码如何重新设置?
前 言当我们忘记了MySQL数据库密码后,该如何重新进行设置? 操作步骤步骤1:cmd打开命名窗口 步骤2:关闭正在运行的MySQL服务(命令:net stop mysql)(如果:此时MySQL正在 ...
- SQL 一次插入多次数据
数据插入 INSERT INTO 表名称 VALUES (值1, 值2,....) 指定所要插入数据的列 INSERT INTO table_name (列1, 列2,...) VALUES (值1, ...
- springcloud费话之Eureka集群
目录: springcloud费话之Eureka基础 springcloud费话之Eureka集群 springcloud费话之Eureka服务访问(restTemplate) springcloud ...
- 如何在C#中使用sqlite,一个简单的类
</pre><pre name="code" class="csharp"> using System.Collections.Gene ...
- YARN的job提交流程
1.客户端向ResourceManagement 提交 运行的请求 (hadoop jar xxxx.jar) 2.ResourceManager进行检查,没有问题的时候,向客户端返回一个共享资源的路 ...
- 常见前端面试题JS部分
1.闭包 2.JS操作和获取cookie //创建cookie function setCookie(name, value, expires, path, domain, secure) { var ...