今日观点!如何使用lock_guard锁定mutex?java中mutex的使用方法
mutex用来协助采取独占方式控制对资源的并发访问,这里的资源可能是一个对象,或多个对象的组合,为了获得独占式的资源访问能力,相应的线程必须锁定mutex,这样可以防止其它线程也锁定该mutex。
(资料图)
下面两条线程如果没有使用mutex来同步,则输出结果会是112233。
mutex g_mutex;void print123() {g_mutex.lock();for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}g_mutex.unlock();} int main(){thread(print123).detach();thread(print123).detach();//123123system("pause");}
你应该确保mutex对象调用lock后,即使发生异常也会调用unlock,否则有可能造成资源被永远锁住或者死锁。
为此我们可以使用lock_guard来进行lock和unlock,lock_guard在构造时会lock,析构时会unlock,使用大括号对可以加快lock_guard的析构,需要注意的是lock_guard一定要分配变量名,否则不会有效果。
void print123(){lock_guardlockGuard(g_mutex);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}}
同一线程多次锁定mutex会导致程序终止,而recursive_mutex则不会,这个mutex允许同一线程多次锁定。
recursive_mutex g_mutex;void print123(){g_mutex.lock();g_mutex.lock();for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}g_mutex.unlock();g_mutex.unlock();}
有时候线程想要锁定mutex,但又不想其它线程已锁定mutex时阻塞,这种情况下可以使用try_lock,它试图锁定mutex,成功就返回true,失败返回false。
为了等待特定长度的时间,你可以使用timed_mutex或recursive_timed_mutex的try_lock_for或try_lock_until方法。
由于try_lock在返回true时会锁定mutex,为了防止lock_guard重复锁定,需要传递参数adopt_lock。
void print123() {if (g_mutex.try_lock()) {lock_guardlockGuard(g_mutex,adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}} else {cout << "mutex locked" <<ENDL;}} int="" main(){thread(print123).detach();thread(print123).detach();system("pause");}通常一个线程一次只锁定一个mutex,然而有时候必须锁定多个mutex,如果一个个锁定,有可能出现锁定了第一个mutex,而无法锁定第二个mutex的情况。这种情况下可以使用全局函数lock锁定多个mutex。mutex g_mutex1;mutex g_mutex2;void print123() {lock(g_mutex1, g_mutex2);lock_guardlockGuard1(g_mutex1, adopt_lock);lock_guardlockGuard2(g_mutex2, adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}} int main(){thread(print123).detach();thread(print123).detach();system("pause");}
使用全局函数try_lock尝试锁定多个mutex,如果锁定所有mutex则返回-1,否则返回第一个失败的mutex的索引(从0开始),并且所有被成功lock的mutex会又被unlock。
mutex g_mutex1;mutex g_mutex2;void print123() {lock(g_mutex1, g_mutex2);lock_guardlockGuard1(g_mutex1, adopt_lock);lock_guardlockGuard2(g_mutex2, adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}}void printLockState(){auto result = try_lock(g_mutex1, g_mutex2);cout << result << endl;if (result == -1) {lock_guardlockGuard1(g_mutex1, adopt_lock);lock_guardlockGuard2(g_mutex2, adopt_lock);}} int main(){thread(print123).detach();thread(printLockState).detach();system("pause");}
除了lock_guard,C++还提供一个类似的类unique_lock,它比lock_guard更灵活,unique_lock允许你明确指定何时锁定或解锁mutex,而lock_guard总是锁定mutex,如果unique_lock析构时mutex仍被锁住,析构函数会自动调用unlock,如果没有则不做任何事。
mutex g_mutex1;timed_mutex g_mutex2; int main(){//尝试锁定mutex,但不会阻塞unique_lockuniqueLock1(g_mutex1, try_to_lock);//尝试锁定mutex,不超过10秒unique_lockuniqueLock2(g_mutex2, chrono::seconds(10));//主动调用lock,try_lock,try_lock_for等才会锁定unique_lockuniqueLock3(g_mutex1, defer_lock);//通过已锁定的mutex初始化unique_lockuniqueLock4(g_mutex1, adopt_lock);//判断有没有锁定mutexcout << (uniqueLock1 ? "locked" : "unlocked")<< endl;cout << uniqueLock1.owns_lock() << endl;//解锁mutexuniqueLock1.unlock();//锁定mutexuniqueLock3.lock();system("pause");}
标签:
相关推荐:
最新新闻:
- 如何给自己的网站接入谷歌联盟?方法步骤 每日消息
- 全球观焦点:系统冗余是什么?冗余的详情介绍
- 今日观点!如何使用lock_guard锁定mutex?java中mutex的使用方法
- 如何下载天地图离线地图瓦片数据?离线地图的下载方式
- 定时器和延时器的区别 定时器和延时器的异步语句|当前关注
- 如何让少儿学好英语字母?26个英文字母背诵顺口溜_视讯
- 互补品的需求曲线图是什么?微观经济学中的供给与需求定律
- 【前沿重器】句子相似度和匹配心法利器 全球即时看
- 西门子PLC7怎么防止错误操作?西门子PLC梯形图编程规则
- WIN+R:程序运行窗口或者打开某个文件
- 正则解析网络运维数据之OneTake 解析网络运维数据:环球焦点
- 世界微动态丨常用计算机的外设有哪些?电脑外设产品什么品牌好?
- 2023年常州春节哪里有烟花?:世界即时
- 视点!高效Transformer、计算机视觉的总结与展望
- 【网络防火墙】PVS的原理及应用_每日简讯
- KMP算法是什么?KMP算法详解_全球消息
- ios系统和安卓系统噪音计测评 哪个更好用?
- 精选!《霍格沃茨之遗》发售1个月倒计时 社区总监:等待是艰难的
- 恐怖逃生解谜游戏《恶娑海》Steam页面上线 2023年第四季度发售_当前滚动
- 鹅鸭杀否认腾讯收购 尚未计划登陆WeGames-天天热推荐
- CCTV6将首播刘亦菲版《花木兰》 尽显东方神韵 世界观热点
- 环球实时:HBO《最后生还者》角色设定改动 山姆的耳朵失聪了
- 今日播报!索尼宣布推出《原神》联动耳机 仅在日本限定发售
- 罗琳引LGBTQ+不满 《霍格沃茨之遗》喜提“反派”tag
- 《幻想三国志 天元异事录》现已在Steam平台免费推出
- 微软《极限竞速:地平线》系列多位人才出走 成立全新工作室
- 《流浪地球2》IMAX/CINITY海报:风格独特宏伟壮观:环球观热点
- 庵野秀明将客串漫改日剧《一刑的乌鸦》剧场版
- 米哈游希望在2030年推出世界级元宇宙产品 10亿人可生活其中
- pdg用什么打开?怎样将pdg文件转为pdf?
- macbook截屏快捷键是什么?macbook截屏快捷键的方法
- win7没有找到Vcomp100.dll?找到Vcomp100.dll的具体步骤
- DNF如何设置窗口?设置DNF窗口的步骤
- skype登陆不上怎么办?skype登陆不上处理方法步骤
- xp系统无法关机是什么原因?无法关机的两种解决办法
- 提示80072efd的错误代码是怎么回事?提示80072efd的错误代码解决方法
- 没下载完的文件如何导入迅雷?迅雷提示"临时文件读取错误"?
- Win8系统配置在哪里?打开Win8系统配置步骤
- 电脑总是弹出Windows安全警告?教大家关闭安全警告的方法
- 初始化网卡信息失败导致不能上网怎么办?初始化网卡信息失败导致不能上网操作过程
- 一键还原精灵怎么彻底删除?一键还原精灵彻底删除两种方法及注意事项
- 会声会影x5序列号及激活码分享 会声会影x5安装步骤
- mom.exe是什么进程?mom.exe文件放在哪?
- 文件夹禁止写入怎么设置?文件夹中不可以存放什么?
- cdr文件打开很慢是什么原因导致的?cdr文件打开很慢的解决方法
- e站需要挂什么加速器 ehviewer网络错误怎么办?
- 设置点击此处进行编辑怎么设置?设置点击此处进行编辑设置操作步骤分享
- 蒲公英SD-WAN组网是什么?蒲公英如何异地组网?
- Win8怎么分区?Win8硬盘分区的方法
- 环球热消息:次世代版MSX迷你掌上主机样品公开 1月15日开众筹
- 黑客推出假冒《宝可梦》NFT卡牌游戏:内含病毒
- 焦点精选!美的集团方洪波:让美的成为真正意义上的全球科技企业
- 多地宣布第一波感染高峰已过,新冠监测体系如何重建?_天天播资讯
- 电脑证书错误怎么办?四个步骤详细教程
- 如何一键ghost8.3硬盘版备份硬盘?一键ghost8.3硬盘版备份方法
- qq应用管理器在哪?qq应用管理器怎么添加应用?
- 苹果AR头显春季发:原型机在测试了!:全球热文
- 三星Galaxy S23系列开始预热 2月2日发布
- 环球即时:3天内获3万辆汽车订单?特斯拉回应不予置评
- 电脑显卡正常温度范围是多少?显卡正常温度介绍
- LOL提示登录失败请重试是怎么回事?原因分析及解决方法
- 电脑开机总是弹出360热点新闻怎么办?360热点资讯怎么彻底删除?
- 思科tftp服务器如何设置根目录?思科tftp服务器命令介绍
- QQ缓存文件是什么?QQ缓存文件应该怎么清除?
- 浏览器提示无法定位序数459怎么办?教大家解决方法
- 提示此网页包含的内容将不使用安全的https连接传送怎么解决?
- bios电池在哪?找寻bios电池在哪的方法步骤
- 产的了却买不到的布洛芬,到底是不是个投资新机会? | MIR DATABANK|新要闻
- 磁盘碎片整理有什么用?介绍磁盘碎片整理的作用
- 打开方式不对导致文件打不开怎么办?还原文件默认打开方式步骤
- coreldraw复制快捷键是什么?cdr怎么等距离连续复制?
- 虚拟光驱怎么用?虚拟光驱的使用方法步骤
- 提示vcomp100.dll丢失问题怎么解决?Vcomp100.dll丢失解决方法
- skype无法登录怎么办?skype无法登录的操作方法
- 电脑提示Shockwave Flash崩溃怎么解决?三种解决方法