当前位置: 首页 > 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;让学生更加直观地了解人体结构和功能。 与传…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...