当前位置: 首页 > news >正文

C++11并发与多线程笔记(6) unique_lock(类模板)

C++11并发与多线程笔记(6) 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的成员函数(前三个与std::defer_lock联合使用)
    • 3.1 lock():加锁。
    • 3.2 unlock():解锁。
    • 3.3 try_lock():尝试给互斥量加锁
    • 3.4 release():
  • 4.unique_lock所有权的传递
    • 4.1 使用move转移
    • 4.2. 在函数中return一个临时变量,也可以实现转移

1、unique_lock取代lock_guard

unique_lock 是一个类模板。
unique_lock 比 lock_guard 灵活很多多出来很多用法),效率差一点,内存占用多一些。
使用:
unique_lock<mutex> myUniLock(myMutex);

2、unique_lock的第二个参数

2.1 std::adopt_lock:

std::adopt_lock:标记作用,表示这个互斥量已经被lock()(方便记忆:已经被lock()收养了,不需要再次lock() ),即不需要在构造函数中lock这个互斥量了。
前提必须提前lock,否则会出错
lock_guard中也可以用这个参数

2.2 std::try_to_lock:

  • 尝试用mutex的lock()去锁定这个mutex,但如果没有锁定成功,会立即返回,不会阻塞在那里
  • 使用try_to_lock的原因是防止其他的线程锁定mutex太长时间,导致本线程一直阻塞在lock 这个地方
    前提不能提前lock();
    owns_lock()方法判断是否拿到锁,如拿到返回true
    实例:
    假设
    线程1 执行下例代码时,先锁定互斥量myMutex1
    ,然后暂停了2s,才继续执行程序。线程1执行的代码如下
bool outMsgProc(int &num)
{unique_lock<mutex> muGuard(myMutex1);chrono::milliseconds time(2000);    //线程暂停2sthis_thread::sleep_for(time);if (!myList.empty()){num = myList.front();myList.pop_front();return true;}return false;
}

在此期间,如果线程2也尝试锁定myMutex1,就只能阻塞,直到线程1释放锁后,才能继续执行。线程2执行的代码如下:

void InMsg()
{for (int i = 0; i < 10000; i++){cout << "插入元素: " << i << endl;unique_lock<mutex> muGuard(myMutex1);myList.push_back(i);			}
}

显然,这样的程序效率不高。线程2花费了太多的时间等待。

我们考虑使用try_to_lock,线程尝试获取锁,如果没有锁定成功,它不会阻塞在那里,可以去执行其他代码。改进后的代码如下:

void InMsg()
{for (int i = 0; i < 10000; i++){cout << "插入元素: " << i << endl;unique_lock<mutex> muGuard(myMutex1, try_to_lock);if (muGuard.owns_lock())// 判断是否拿到锁{myList.push_back(i);}else{//没有拿到锁时,执行的代码}}
}

2.3 std::defer_lock:

  • 如果没有第二个参数就对mutex进行加锁,加上defer_lock是始化了一个没有加锁的mutex
  • 不给它加锁的目的是以后可以调用unique_lock的一些方法
  • 前提不能提前lock

3、unique_lock的成员函数(前三个与std::defer_lock联合使用)

3.1 lock():加锁。

unique_lock<mutex> muGuard(myMutex, defer_lock);
muGuard.lock();//手动加锁

不用自己unlock();

3.2 unlock():解锁。

unique_lock<mutex> muGuard(myMutex, defer_lock);
muGuard.lock();
//处理一些共享代码
muGuard.unlock();
//临时处理一些非共享代码
muGuard.lock();
//处理一些共享代码,处理完之后,自动解锁

3.3 try_lock():尝试给互斥量加锁

try_to_lock是unique_lock的第二个参数,try_lock()是unique_lock()的成员变量。
如果拿不到锁,返回false,否则返回true(然后上锁)。

 unique_lock<mutex>muGuard(myMutex, defer_lock);//mutex1.lock();//自动解锁if (muGuard.try_lock() == true) {cout << "插入数据: " << num << endl;test_list.push_back(num);}else {cout << "in_list()执行,但没有拿到锁" << num << endl;}

3.4 release():

release():就是解除绑定,返回它所管理的mutex对象的指针,并释放所有权。

  1. unique_lock<mutex>muGuard(myMutex1);
    相当于把myMutex(mutex对象)和 muGuard绑定在了一起
  2. mutex* ptx =muGuard.release();
    也就是说 muGuard和mutex不在有联系,后续myMutex所有权由ptx接管,如果原来mutex对象处理加锁状态,就需要ptx在以后进行解锁了。
for (int num = 0; num < 10000; num++) {unique_lock<mutex> muGuard(myMutex);mutex* ptx = muGuard.release();//解除myMutex1(mutex对象)和 muGuard绑定//操作事务test_list.push_back(num);ptx->unlock();//myMutex1所有权由ptx接管,由ptx进行解锁
}

lock的代码段越少,执行越快,整个程序的运行效率越高。

  • 锁住的代码少,叫做粒度细,执行效率
  • 锁住的代码多,叫做粒度粗,执行效率
    -只锁定共享的数据

4.unique_lock所有权的传递

unique_lock<mutex> muGuard1(myMutex);
把myMutex1和muGuard绑定在了一起,也就是muGuard拥有myMutex1的所有权

4.1 使用move转移

unique_lock<mutex> muGuard2(std::move(muGuard1));
之前muGuard1拥有myMutex的所有权,muGuard1可以把自己对myMutex的所有权转移,但是不能复制。现在muGuard2拥有myMutex的所有权。

4.2. 在函数中return一个临时变量,也可以实现转移

unique_lock<mutex> aFunction()
{unique_lock<mutex> tmpguard(myMutex);//移动构造函数那里讲从函数返回一个局部的unique_lock对象是可以的//返回这种局部对象会导致系统生成临时的unique_lock对象,并调用unique_lock的移动构造函数return tmpguard;
}
// 然后就可以在外层调用,在muGuard2具有对myMutex的所有权
std::unique_lock<std::mutex> muGuard2 = aFunction();

相关文章:

C++11并发与多线程笔记(6) unique_lock(类模板)

C11并发与多线程笔记&#xff08;6&#xff09; unique_lock&#xff08;类模板&#xff09; 1、unique_lock取代lock_guard2、unique_lock的第二个参数2.1 std::adopt_lock&#xff1a;2.2 std::try_to_lock&#xff1a;2.3 std::defer_lock&#xff1a; 3、unique_lock的成员…...

计算机网络——OSI与TCP/IP各层的结构与功能,都有哪些协议?

文章目录 一 OSI与TCP/IP各层的结构与功能,都有哪些协议?1.1 应用层1.2 运输层1.3 网络层1.4 数据链路层1.5 物理层1.6 总结一下 二 ⭐TCP 三次握手和四次挥手(面试常客)2.1 TCP 三次握手漫画图解2.2 为什么要三次握手⭐2.3 第2次握手传回了ACK&#xff0c;为什么还要传回SYN&…...

Win7 x86 家庭版SP1 配置 Python 开发环境

1 Win7 下载地址 来源于 MSDN, 我告诉你 - 做一个安静的工具站 ed2k://|file|cn_windows_7_home_basic_with_sp1_x86_dvd_u_676500.iso|2653276160|843E7A78F2126FAC726CF5342710082D|/ 2 Python 版本选择 Python 3.7.9 Python Release Python 3.7.9 | Python.org 3 Pychar…...

从零玩转系列之微信支付实战PC端装修我的订单页面 | 技术创作特训营第一期

一、前言 欢迎来到本期的博客&#xff01;本篇文章是 PC 端的结尾了,前面经历过九个章节到本章节刚刚好十章节感谢观看我的文章,那么接下来我们将要编写的是我的订单页面. GGBOM! 本篇完毕后将是 UniApp 的篇章感受移动端的诱惑 &#x1f497; 本次为前端知识点如果不懂前段可以…...

ChatGPT和Claude的能力全测评

创造性思维/语言 提示&#xff1a;“写一首 4 行诗&#xff0c;每行只有 3 个词&#xff0c;描写重庆” ChatGPT写诗&#x1f447; Claude写诗&#x1f447; 仁者见仁&#xff0c;您怎么看谁更强&#xff1f; 提示&#xff1a; "如果你随机选择这个问题的答案&#xff0c;…...

ffmpeg简介

1.什么是ffmpeg ffmpeg即使一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件&#xff0c;作为编解码开发套件&#xff0c;它为开发者提供了丰富的音视频处理的调用接口。 ffmpeg提供了多种媒体格式的封装和解封装&#xff0c;包括多种音视频编码、多种协议…...

AI绘画 stable diffusion Midjourney 官方GPT文档 AIGC百科全书资料收集

教学AI绘画 AIGC工具 SD教程 ###Redis面试题 单机Redis的qps大概是多少&#xff1f; 项目中用到了哪些Redis的数据类型&#xff1f;为什么这么用&#xff1f; Redis的key到了过期时间就被删除了吗&#xff1f;简述下Redis的过期策略&#xff1f; Redis有哪几种内存淘汰策略…...

Lombok注解大全

一、安装插件&#xff0c;eclipse 对于 lombok 的支持 二、引入依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version> <!-- Spring Boot 项目此部分可以不写 --&g…...

STM32--ADC模数转换

文章目录 ADC简介逐次逼近型ADCADC框图转换模式数据对齐转换时间校准ADC基本结构ADC单通道工程代码&#xff1a; ADC简介 STM32的ADC&#xff08;Analog-Digital Converter&#xff09;模拟-数字转换器&#xff0c;是一种逐次逼近型模拟数字转换器&#xff0c;可以将引脚上连续…...

陕西科技大学改考408!附考情分析

改考信息 8月14日&#xff0c;陕西科技大学公布了2024年硕士研究生招生目录&#xff08;初稿&#xff09;&#xff0c;其中不难发现083500软件工程初试专业课由819数据结构改为408计算机学科专业基础 图片&#xff1a;陕西科技大学24专业目录-软件工程学硕 https://yjszs.sus…...

02.有监督算法——朴素贝叶斯

1.朴素贝叶斯 1.1条件概率 如果两个事件A和B不是相互独立&#xff0c;并且知道事件B已经发生&#xff0c;A在B中的条件概率&#xff1a; P ( A ∣ B ) P ( A B ) P ( B ) P(A|B) {P(AB) \over P(B)} P(A∣B)P(B)P(AB)​ 先验概率&#xff1a; 根据以往经验和分析得到的概…...

前端新手学习路线

文章目录 前端学习路线&#xff01;特点符号表大纲前言 - 学编程需要的特质一、前端入门⭐️ 开发工具浏览器编辑器文档笔记 ⭐️ HTML⭐️ CSS⭐️ JavaScript✅ ES6 特性 二、巩固基础前端基础知识计算机基础✅ 算法和数据结构✅ 计算机网络✅ 操作系统 软件开发基础✅ 设计模…...

vactor中迭代器失效问题

目录 什么是迭代器失效导致迭代器失效的操作VS和g环境下对与迭代器失效的态度 什么是迭代器失效 迭代器的底层其实就是一个指针&#xff0c;或者对指针进行了封装 vector的迭代器就是一个指针T* 一个迭代器指向某一个空间&#xff0c;此时这块空间被释放了&#xff0c;这个迭…...

电子商务防火墙的作用

1.作为网络安全的屏障 只有经过精心选择的应用协议才能通过防火墙&#xff0c;可使网络环境变得更安全。如 防火墙可以禁止 NFS 协议进出受保护的网络&#xff0c;这样外部的攻击者就不可能利用这些 脆弱的协议来攻击内部网络。防火墙同时可以保护网络免受基于路由的攻击&am…...

「UG/NX」Block UI 选择特征SelectFeature

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...

【数据分享】2006-2021年我国城市级别的节约用水相关指标(免费获取\20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况&#xff0c;在之前的文章中&#xff0c;我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…...

Azure不可变Blob存储

文章目录 Azure不可变Blob存储介绍Azure不可变性策略实战演练 Azure不可变Blob存储介绍 不可变的存储是一种用于存储业务关键型 Blob 数据的存储方式。与可变存储相反&#xff0c;不可变存储的特点是一旦数据被写入后&#xff0c;便无法再对其进行修改或删除。这种存储方式提供…...

No mapping found for HTTP request with URI

参考: 参考地址 说明 ssm老项目,接过来别人的项目 临时建了一个Controller方便测试用的,结果访问掉不通,报: No mapping found for HTTP request with URIxxxx 这样的错误 解决办法 看了下web,xml配置 在 webmvc-config.xml 配置文件里面添加了几行配置 说明: com.iph.h…...

视频转云存的痛点

现在整个运营商体系里面&#xff0c;有大量的视频转云存储的需求&#xff0c;但是视频云存储有一个比较大的痛点&#xff0c;就是成本&#xff01; 成本一&#xff1a;存储成本&#xff1b; 我们以1000路2M视频转云存&#xff0c;存储时间为90天为例&#xff08;B端存储时间有…...

3D医学教学虚拟仿真系统:身临其境感受人体结构和功能

3D医学教学虚拟仿真系统是一种基于虚拟现实技术的教学工具&#xff0c;它可以帮助学生更好地理解和掌握医学知识。这种课件通常包括人体解剖学、生理学、病理学等方面的教学内容&#xff0c;通过三维立体的图像和动画展示&#xff0c;让学生更加直观地了解人体结构和功能。 与传…...

如何高效获取网盘直链:8大平台的完整解决方案

如何高效获取网盘直链&#xff1a;8大平台的完整解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅…...

重构计算机历史叙事:挖掘被遗忘的贡献者与构建包容性科技未来

1. 项目概述&#xff1a;为什么我们需要重写计算机历史如果你问一个对计算机历史稍有了解的人&#xff0c;让他列举几位先驱&#xff0c;大概率会听到冯诺依曼、艾伦图灵、比尔盖茨、史蒂夫乔布斯这些名字。这个名单很长&#xff0c;但有一个共同点&#xff1a;他们几乎都是白人…...

如何高效配置ClickHouse连接器:专业用户的完整指南

如何高效配置ClickHouse连接器&#xff1a;专业用户的完整指南 【免费下载链接】clickhouse-odbc ODBC driver for ClickHouse 项目地址: https://gitcode.com/gh_mirrors/cl/clickhouse-odbc ClickHouse ODBC驱动是连接ClickHouse数据库与各类数据分析工具的关键桥梁&a…...

Neo-Launcher数据库架构:数据存储和管理的深度解析

Neo-Launcher数据库架构&#xff1a;数据存储和管理的深度解析 【免费下载链接】Neo-Launcher Neo-Launcher 项目地址: https://gitcode.com/gh_mirrors/ne/Neo-Launcher Neo-Launcher是一款由Neo Collective开发的开源启动器应用&#xff0c;其高效的数据存储和管理系统…...

基于Electron的本地字幕翻译工具开发全解析

1. 项目概述&#xff1a;一个本地化的字幕翻译利器最近在折腾一些海外纪录片和课程视频&#xff0c;发现一个挺普遍的需求&#xff1a;手头有外文字幕文件&#xff08;比如SRT、ASS&#xff09;&#xff0c;想把它翻译成中文&#xff0c;但又不希望把视频或字幕上传到任何在线服…...

基于MCP协议构建AI助手业务工具适配器:从原理到实践

1. 项目概述&#xff1a;用MCP协议为AI助手装上“业务之眼”如果你和我一样&#xff0c;日常开发中需要频繁地在Stripe看支付数据、在Sentry查线上错误、在Notion里翻文档、在Linear跟进任务状态&#xff0c;那你一定懂那种在十几个浏览器标签页和不同SaaS平台间反复横跳的疲惫…...

VTOL无人机微多普勒特征分析与6G感知技术

1. VTOL无人机微多普勒特征分析的技术背景垂直起降&#xff08;VTOL&#xff09;无人机因其独特的飞行能力在军事和民用领域获得广泛应用&#xff0c;但同时也带来了空域管理的新挑战。传统雷达识别方法主要依赖目标的宏观运动特征&#xff0c;难以精确区分VTOL的不同飞行阶段。…...

口碑好的芯片老化座哪家专业

在芯片制造与测试领域&#xff0c;芯片老化座是一个至关重要的设备。它能够模拟芯片在长期使用中的各种环境条件&#xff0c;提前发现潜在问题&#xff0c;确保芯片在实际应用中的稳定性和可靠性。那么&#xff0c;口碑好的芯片老化座哪家专业呢&#xff1f;今天我们就来详细探…...

基于Next.js 15与React 19构建现代化个人作品集:技术选型与工程实践

1. 项目概述&#xff1a;为什么选择 Next.js 15 构建现代个人作品集 作为一名在前后端领域摸爬滚打了十多年的开发者&#xff0c;我见过也亲手搭建过无数种个人作品集网站。从早期的纯静态 HTML/CSS&#xff0c;到 jQuery 时代&#xff0c;再到 React/Vue 等框架的兴起&#x…...

Go语言安全编码实践:常见漏洞与防护

Go语言安全编码实践&#xff1a;常见漏洞与防护 1. 安全编码原则 安全编码是防止漏洞的根本&#xff0c;包括输入验证、输出编码、最小权限等原则。 2. 安全工具 package securityimport ("regexp""strings" )type Validator struct {emailRegex *regexp.R…...