unique_lock详解

C++11并发与多线程笔记(6) unique_lock(类模板)详解 第六节 unique_lock(类模板)详解 1.unique_lock取代lock_guard unique_lock比lock_guard灵活很多(多出来很多用法),效率差一点。 unique_lock myUniLock(myMutex); 2.unique_lock的第二个参数 2.1 std::adopt_lock: 表示这个互斥量已经被lock(),即不需要在构造函数中lock这个互斥量了。 前提:必须提前lock lock_guard中也可以用这个参数 2.2 std::try_to_l 阅读详情

一、unique_lock取代lock_guard

unique_lock是个类模板,工作中,一般lock_guard(推荐使用);
lock_guard取代了mutex的lock()和unlock()。
unique_lock比lock_guard灵活很多灵活很多;效率上差一点,内存占用多一点。
std::lock_guard<std::mutex> sbguard(my_mutex);直接换成std::unique_lock<std::mutex> sbguard(my_mutex);

二、unique_lock的第二个参数

lock_guard可以带第二个参数:

std::lock_guard<std::mutex> sbguard(my_mutex,std::adopt_lock);

//adopt_lock标记作用,unique_lock也支持

2.1 std::adopt_lock:

表示这个互斥量已经被lock了(你必须提前把互斥量lock了)

std::adopt_lock标记的效果就是假设调用方线程已经拥有了互斥的所有权(已经lock()成功了),通知lock_guard不需要在构造函数中lock这个互斥量了
unique_lock也可以带std::adopt_lock标记,含义相同

2.2 std::try_to_lock

【引言】
std::mutex::lock特点:
拿到锁之后立即返回,拿不到锁一直卡着。

我们会尝试用mutex的lock()去锁定这个mutex,但如果没锁定成功,我也会立即返回,并不会阻塞在那里;
用这个try_to_lock的前提是你自己不能先去lock。

std::unique_lock<std::mutex> sb_guard(my_mutex1,std::try_to_lock);
 if (sb_guard.owns_lock())
{
	msgRecvQueue.push_back(i);
}
else
{
	cout << "inMsgRecvQueue()执行,但没有拿到锁,只能干点别的事" << i << endl;
}

2.1 2.2小结:
adopt_lock前提要把互斥量锁住了,try_to_lock的前提是你自己不能先去lock(只能用unique_lock调用构造函数锁)

2.3 std::defer_lock

前提是你不能自己先lock,否则会报异常。
意思是就是没有给mutex加锁,初始化了一个没有加锁的mutex。
我们借着unique_lock的话题,来介绍一些unqiue_lock的重要成员函数

std::unique_lock<std::mutex> sbguard(my_mutex1,std::defer_lock);//没有加锁的my_mutex
sbguard.lock(); //咱们不用自己unlock()

三、unique_lock的成员函数

3.1 lock()

3.2 unlock()

 std::unique_lock<std::mutex> sbguard(my_mutex1,std::defer_lock);//没有加锁的my_mutex
sbguard.lock(); //咱们不用自己unlock()

//因为有一些非共享的代码要处理
 sbguard.unlock();
//处理一些非共享代码

sbguard.lock();
msgRecvQueue.push_back(i);
sbguard.unlock();	//画蛇添足,但也可以

3.3 try_lock()

尝试给互斥量加锁,如果拿不到锁,则返回false,如果拿到了锁,返回true,这个函数不阻塞

std::unique_lock<std::mutex> sbguard(my_mutex1,std::defer_lock);//没有加锁的my_mutex
if (sbguard.try_lock() == true)
{
	msgRecvQueue.push_back(i);
}
else
{
	cout << "inMsgRecvQueue()执行,但没有拿到锁,只能干点别的事" << i << endl;
}

std::unique_lock::try_lock()和std::defer_lock()配合使用

3.4 release()

返回它所管理的mutex对象指针,并释放所有权;也就是说,这个unique_lock和mutex不再有关系

严格区分unlock()和release()区别,不要混淆。

std::unique_lock<std::mutex> sbguard(my_mutex1);

相当于把unique_lock和std::mutex类对象my_mutex1绑定在一起
如果原来mutex对象处于加锁状态,你有责任接管过来并负责解锁。

std::unique_lock<std::mutex> sbguard(my_mutex1);//没有加锁的my_mutex
std::mutex* ptx = sbguard.release();
msgRecvQueue.push_back(i);
ptx->unlock();

注意:
lock锁住的代码段越少,执行越快,整个程序运行效率越高。
lock锁住的代码多少,称为锁的粒度,粒度一般用粗细来描述;
a) 锁住的代码少,这个粒度叫细。执行效率高;
b) 锁住的代码多,粒度叫粗,执行效率就低。

四、unique_lock所有权的传递

unique_lock需要和一个mutex对象绑定到一起发挥作用(配合使用、管理)
不能将一个mutex对象和两个unique_lock绑定在一起
这就是所有权的概念

std::unique_lock<std::mutex> sbguard(my_mutex1);

sbguard拥有my_mutex1的所有权
sbguard可以把自己对mutex类对象(my_mutex1)的所有权转移给其他unique_lock对象;
所以,unique_lock对象 这个mutex所有权是属于可以转移,但是不能复制。

4.1 通过std::move()转移所有权

std::unique_lock<std::mutex> sbguard(my_mutex1);
std::unique_lock<std::mutex> sbguard2(std::move(sbguard));//移动语义,现在相当于sbguard2和my_mutex1绑定到一起了,现在sbguard指向空,sbguard已经解除了my_mutex1的管理,由sbguard2接管

4.2 通过函数返回值return std::unique_lock<std::mutex>转移所有权

std::unique_lock<std::mutex> rtn_unique_lock()
{
        std::unique_lock<std::mutex> tmpguard(my_mutex1);
        return tmpguard; //从函数返回一个局部的unique_lock对象是可以的。三章14节讲过移动构造函数。
                         //返回这种局部对象tmpguard会导致系统生成临时的unique_lock对象,并调用unqiue
}
C++(11):unique_lock unique_lock是lock_guard的加强版,它具有 lock_guard 的所有功能,同时具有如下特点: 创建时可以不锁定(通过指定第二个参数为std::defer_lock) 可以随时加锁解锁(通过lock,try_lock, unlock) 允许延迟锁定(通过try_lock_for),限时锁定(通过 try_lock_until) 不可复制,可移动(通过移动构造函数或移动赋值函数转移所有权) 可以主动释放所有权(通过release) 作用域规则同 lock_grard,析构时自动 阅读详情

相关推荐

C++使用unique_lock实现多重锁机制

现代的计算机性能很强大,可以实现多线程并发。随之而来引入了另一个问题:“数据竞争”,这个问题是并发编程必须面对的。还有一种情形,当我们需要同时满足获取多个锁才能进行下一步操作该怎么办呢?最简单的方法是定义3个mutex,依次lock(),当全部满足的时候再进行下一步。看起来似乎可行,但是对于场景比较复杂的情况可能引来一个非常危险的后果“死锁”:想想那样一种场景,你所需要的锁也同样被其他很多线程需要,随着锁的数量增加,“死锁”的概率随之增大,无形之中增加了风险。

jiexijihe945的博客 1903

unique_lock 详解

(1) unique_lock 取代lock_guard (2)unique_lock的第二个参数 2.1.std::adopt_lock 2.2 std::try_to_lock 2.3 std::defer_lock (3) unique_lock的成员函数 3.1 lock 3.2 unlock() 3.3 try_lock() 3.4 release() (4) unique_lock 所有权的传递 unique_lock 取代lock_guard unique_lock

weixin_42136255的博客 1万+

AD/Protel老手才知道的PCB过孔查看技巧:3分钟分清通孔、盲孔和埋孔

本文为PCB设计工程师提供了在Altium Designer/Protel中快速鉴别通孔、盲孔和埋孔的实用技巧。通过层叠管理器、高级筛选工具和实战五步法,帮助用户在3分钟内精准识别过孔类型,提升设计效率和电路性能。特别适合处理高密度HDI板卡中的复杂过孔布局。

weixin_29164497的博客 575

17.6 C++并发与多线程-unique_lock详解

unique_lock是一个类模板,它的功能与lock_guard类似,但是比lock_guard更灵活。在日常的开发工作中,一般情况下,lock_guard就够用了(推荐优先考虑使用lock_guard),但是,读者以后可能参与的实际项目千奇百怪,说不准就需要用unique_lock里面的功能,而且如果阅读别人的代码,也可能会遇到unique_lock,所以这里讲一讲unique_lock。

migu123的专栏 3109

Dify DSL文件分享 Dify讨论群 大模型token资源等(持续收集更新)

基于LLMOps平台-Dify的一站式学习平台。包含不限于:Dify案例、DSL文件分享、模型接入、Dify交流讨论等各类资源分享。

同名公众号:dify实验室 3716

NC数据预处理避坑指南:从MATLAB读取到GeoTIFF导出,解决坐标翻转与值域异常

本文详细解析了NC数据预处理中的常见问题,包括MATLAB读取时的坐标翻转与GeoTIFF导出时的值域异常。通过实战案例,介绍了如何解决矩阵方向错乱、处理FillValue与scale_factor、精准移植空间参考等关键问题,帮助研究者高效完成气象数据的批量处理与GIS兼容性验证。

weixin_30788619的博客 654

6.unique_lock详解

目录 一、unique_lock取代lock_guard unique_lock是个类模板,工作中,一般使用lock_guard(推荐使用!) lock_guard取代了mutex的lock()和unlock(); unique_lock比lock_guard灵活很多,效率上差一点,内存占用多一点。 二、unique_lock的第二个参数 lock_guard可以带第二个参数: std::lock_guard<std::mutex> sbguard1(my_mutex1, std::adopt

weixin_42636062的博客 4520

Deepseek 10分钟化身理性荐股神器:触碰程序员不敢想的天花板

在这个消息疯狂、波动频繁的市场,“理性”两字显得弥足珍贵。通过Deepseek+AkShare+Aktools+Dify四位一体的方案,能帮我们降低信息搜集成本,并在短期投资领域搭建出一套“可解释、低门槛、易定制”的量化荐股流程。不要再盲目听小道消息或依赖情绪驱动,不妨给自己一个机会,让数据说话。而要注意的是,“理性荐股”并非万能,它只是工具,最终的收益还得依赖投资者自身对风险和机遇的权衡。祝大家都能在这股市里收获理性的底气,寻得更精准的入场时机。

qqxdh的博客 3753

52 C++ unique_lock 替代 lock_guard 详解

返回它所管理的mutex对象指针,并释放所有权,也就是说:这个uique_lock 和mutex不在有关系,如果这时候mutex处理加锁状态,则要程序员自己对这个mutex进行unlock操作。我们会尝试用mutex的lock()去锁定这个mutex,但是如果没有锁定成功,我也会立即返回,并不会阻塞在这里。好处是不用管unlock(),在 sbguard1的析构函数调用的时候,会调用 mymutex1的析构函数。之前的lock_guard是要在析构函数调用的时候,才会调用 mutex.unlock();

hunandede的博客 1236

(十二)深入理解蓝牙BLE之“移植Bluez 5.18源码到嵌入式平台”

在某嵌入式平台进行蓝牙开发,发现上面居然没有btmon,hciattach,hcitool等蓝牙调试工具,无奈之下,只好移植bluez协议栈到目标嵌入式平台,建议移植5.18版本(最新的5.54版本居然hcitool等工具不是默认编译的,需要修改Makefile才可以)。 看到很多讲解移植过程的文章都是需要积分的,觉得写一篇免积分的文章还是有些意义的,欢迎同行来交流。 移植环境:Linux ubuntu 目标平台:sigmastar 星宸科技 配置交叉编译工具链:export PATH=$PATH:

2964

股票价格预测的秘密武器:用C#实现蒙特卡洛路径模拟,轻松掌握市场波动规律!

摘要: 蒙特卡洛模拟是股票预测的有效工具,通过随机抽样模拟价格路径,克服传统技术分析的局限性。其核心模型是几何布朗运动(GBM),描述股价随机变化过程。C#实现的关键步骤包括:1)获取输入参数;2)生成随机数路径;3)分析结果。该方法不预测具体价格,而是提供可能的价格范围,帮助投资者评估风险。代码结构清晰,分为输入、模拟、分析和可视化四个模块,通过参数封装提高可读性,适用于不确定市场的概率预测。

墨夶的博客 601

4 —— unique_lock详解

一 unique_lock取代lock_guard   unique_lock是个类模板,工作中,一般使用lock_guard。因为unqiue_lock占用的内存更多,效率底一些。但是unique_lock更加灵活,它的构造函数的第二个参数可以有其它的形式,下面会提到。同时,uniuqe_lock与lock_guard一样自动对绑定的互斥量自动加锁,解锁。 二 unique_lock的构造函数 ...

baboon_chen 654

Python实战:打造学生信息管理系统

通过本教程,我们构建了一个简单的学生信息管理系统,实现了基本的添加、删除、修改和查询功能。当然,这个系统还有很多可以改进和扩展的地方,比如添加用户界面、增加数据持久化功能、支持批量操作等。简介:本文将介绍如何使用Python编写一个功能齐全的学生信息管理系统,包括添加、删除、修改和查询学生信息的基本操作。学生信息管理系统是学校日常管理中不可或缺的一部分,它能够帮助管理人员快速、准确地管理学生信息,提高工作效率。为了实现上述功能,我们可以设计一个包含学生信息的字典,并使用函数来封装各个操作。

铭渊老黄 1490

C++ unique_lock详解

头文件<mutex> 相比于lock_guard,更灵活,但效率上差一点,内存也占用更多. 可以看到unique_lock也含有第二个参数的构造函数.

qq_44800780的博客 3270

基于STM32、HAL库的ADE7880ACPZ-RL电能计量芯片驱动程序设计

@retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)* @retval 状态 (ADE7880_OK或ADE7880_ERROR)PA6 (MISO) <--> SDO (SPI数据输出)PB0 (CS) <--> /CS (片选,低有效)

corlin6688的博客 668

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C++11之多线程: unique_lock详解

目录 1.unique_lock取代lock_guard 2. unique_lock的第二个参数 2.1 std::adopt_lock 2.2 std::try_to_lock 2.3 std::defer_lock 3. unique_lock的成员函数 3.1 lock(),加锁 3.2 unlock(),解锁 3.3 try_lock() 3.4 release() 4. unique_lock所有权的传递 1.unique_lock取代lock_guard uni.

随意的风的专栏 7133

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++ 中 lock guard 与 unique lock 详解:互斥锁管理的两种利器

lock_guard和lock_guard 是默认首选:对于简单的临界区保护,lock_guard是最佳选择。它足够轻量(仅存储一个引用)、意图清晰、零开销。绝大多数需要“进入时加锁、退出时解锁”的场景都应该使用lock_guard。unique_lock 用于需要灵活控制的场景与配合(这是最关键的区分点——必须接受需要手动解锁/重锁使用defer_lock延迟加锁使用尝试加锁(非阻塞)需要转移锁的所有权(移动语义)两者的本质关系是lock_guard的超集,提供了所有。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 606

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

17.6 unique_lock详解

unique_lock详解

zzyzxb的博客 879

C++11多线程 unique_lock详解

目录 1.unique_lock取代lock_guard 2. unique_lock的第二个参数 2.1 std::adopt_lock 2.2 std::try_to_lock 2.3 std::defer_lock 3. unique_lock的成员函数 3.1 lock(),加锁 3.2 unlock(),解锁 3.3 try_lock() 3.4 release() ...

u012507022的博客 8万+
上一篇: 多线程共享数据的保护+互斥量概念、用法、死锁演示及解决详解(std::lock()、std::adopt_lock)
下一篇: 单例设计模式共享数据分析、解决、call_once
HITXJ
博客等级 码龄7年 8粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值