线程--线程同步
这里写目录标题
- 同步概念
- 线程同步概念
- 数据混乱原因
- 互斥量
- 原理
- 锁的注意事项
- 1、cpu时间轮片
- 2、建议锁
- 总结
- 使用锁来管理线程同步
- 问题产生
- 主要函数
- init、destory
- lock、unlock
- 代码
- 注意事项(锁的粒度)
- try锁
- 死锁
- 出现原因
- 图解
- 读写锁
- 特性
- 图解
- 函数
- 总览
- init、destroy
- rdlock、tryrdlock
- wrlock、trywrlock
- unlock
- 代码
- 条件变量
- 二级目录
- 二级目录
- 二级目录
- 信号量
- 二级目录
- 二级目录
- 二级目录
同步概念
线程同步概念
数据混乱原因
互斥量
原理
多个线程操作共享区时,每个线程访问时,会加上一把锁,只允许某单个线程对共享区进行操作,操作完之后,再解锁,表示允许其他线程访问
而这个锁就叫互斥锁,这个互斥锁只有一把,各个线程争抢这把锁,谁先拿到锁,谁先有操作共享区的权利
锁的注意事项
1、cpu时间轮片
当线程T1执行写入0的操作的过程中,T1的cpu时间到了,那么就会让出cpu,之后给到T2,但是由于此时共享区还在被锁的状态,所以T2只好阻塞在锁上,等待锁的解锁,之后,过段时间,就会又让出cpu给到T3,T3此时也会阻塞在锁上,然后过段时间,再次让出cpu给T1,T1此时拿着锁,可以操作共享区,所有会继续上次中断的地方继续操作共享区
2、建议锁
假如说,当T3拿到cpu时间之后,并不阻塞在锁上,而是就要强制访问共享区,那么也是可以的,只不过会造成数据混乱而已,所以,互斥锁并不是一个强制的概念,而是一个建议,他的强制性体现在代码逻辑上,而不是底层系统的强制操作,如果T3的代码逻辑中使用了锁,那么T3就无法访问共享区,当然T3也可以不使用锁,直接访问,代码层面也是可以运行的
总结
使用锁来管理线程同步
问题产生
使用两个线程,同时向“公共输出”(共享区)写数据,没有加锁机制
效果:
打印完全随机,各个线程的一帧数据写入都会被其他线程打断、插入其他数据
主要函数
其中,trylock函数,表示会让当前线程尝试加锁,看看能不能加上,加不上了先去做自己的事,过段时间再来尝试,而不是像之前说的“阻塞在锁上”
而五个函数的下面是一个变量,这个变量就是互斥量,就是锁本身,他只有0、1两种取值
大概流程:
init、destory
对于init:
参数一:传入互斥锁的地址,
参数二:互斥锁的属性,如果想使用默认属性,那么就传NULL
其中,对于restrict关键字:
他是用来修饰指针的,
可以说,这个内存就认定了这个指针,注意与指针认定内存有区别(顶层const)
对于顶层const,是站在指针的角度,对于一个指针来说,他只存储某块内存的地址,但是该地址还可以被其他指针所存储和操作
而对于restrict,是站在内存的角度,对于一块内存的操作来说,他只认定那个指针,其他指针无法操作该内存
返回值:成功:0。失败:返回error number
lock、unlock
代码
1、创建互斥锁(全局变量)
2、在主线程创建子线程之前,要将锁初始化完毕
并在最后所有线程结束后销毁互斥锁:
3、在每个线程访问共享区的前后进行加锁和解锁:
子线程:
主线程:
效果:
每个线程的数据被完整的加入到了共享区
注意事项(锁的粒度)
假如说,我们把解锁的操作移到循环步的最后:
可以看到,主线程和子线程都使用加锁和解锁把原来的所有代码包裹起来,这样结构上确实很清晰
但是:
可以看到,最终要么只执行主线程,要么只执行子线程
原因:
由于线程在解锁之后立马就进入下一个循环,使得解锁之后该线程又拿到了锁,所以,就会一直保持一个线程,另一个线程无法拿到锁
所以:
我们的加锁和解锁操作,只在访问共享区的前后,立即执行,锁尽量只包含访问共享区的代码部分
最好在解锁之后,加个sleep
补充:
可以将互斥锁的操作看成整数,
初始化时,值为1,表示当前锁可以被拿取并使用
之后,加锁时,–,那么值变为0,表示已经加锁,锁目前被占用,无法使用,其他线程就无法使用锁,无法访问共享区了
最后,解锁时,++,值变回1,表示再次可以使用
try锁
注意,他有一个点:即加锁失败会直接返回错误号,并且不阻塞
lock如果加锁失败,是会阻塞在锁上等待锁的释放的
死锁
出现原因
图解
对于第一种情况:
反复加锁:
当一个线程去拿某个共享区的锁时,已经拿到了,之后,这个线程再次去lock
那么此时由于第一次这个锁已经被lock了。所以,第二次的lock会失败然后阻塞在锁上等待锁的释放,而能释放锁的线程就是当前阻塞的这个线程,所以,也就导致线程永远无法继续执行了,所以造成死锁
对于第二种情况:
如果有两个共享区,那么每个共享区都有一个锁,如果有一种场景:一个线程必须要拿到两个锁,才能继续向下执行自己的业务
此时,线程1拿到A锁,之后他想去拿B锁,但是,被线程2抢先一步拿到B锁,此时,线程1lock会失败并且阻塞在B锁,而线程2拿到B锁之后去拿A锁,由于A锁被线程1拿到了,所以线程2也会阻塞在A锁,这样,两个线程都在阻塞,且阻塞在一个“正处于阻塞”的线程所掌握的锁上,也就都无法继续向下执行了,造成死锁
读写锁
特性
读锁可以共享,写锁与上面的互斥锁是一样的
图解
1、当所有的锁都是读锁:
遵循读共享的原则,那么此时四个锁都可以加锁成功,共同去读数据
2、假如说两个线程(一个是读、一个是写)同时来加锁:
假如某一时刻,线程1来加读锁,线程2加写锁,那么会优先让写锁加锁成功,注意,此时指的是某一刻,两个线程,同时加锁,这种情况很少出现
3、已经有两个读线程加了读锁,此时来了两个写线程,想要加写锁:
如果已经有两个读线程加了读锁,此时来了两个写线程,想要加写锁,那么注意,上面说的写锁的优先级高,是在r、w锁同时来请求加锁的时刻才会去考虑,现在r以及加上了锁,那么w锁就必须阻塞等待锁被释放,并且是所有的r线程都释放完毕,w锁才能加上
但是,此时有两把w锁,写锁是不会共享的,所以只能有一个线程加上w锁,这个就要争抢了,一旦一个加上了w锁,另一个w线程就要继续阻塞等待,这就是“写独占”
4、线程1已经加上了r锁,此时,同时来了两个w锁和一个r锁:
线程1已经加上了r锁,此时,同时来了两个w锁和一个r锁,这个时候,r锁是不能直接加锁的,虽然读锁共享,但是要先遵循“写锁优先”。对于同时来的情况,只有w锁处理完了。才会去处理r锁,所以,此时T3会等待T2、T4加锁解锁之后,才能去加锁,T2、T4也要先等待T1把锁释放了才能去加锁
函数
总览
其中,初始化锁、销毁锁、解锁操作都是一个(解锁是一个,是因为只有一个锁,不管指定是读锁还是写锁,都是同一把锁)
而加锁、和try锁,都是两个,因为这里涉及到是指定写锁还是读锁
init、destroy
rdlock、tryrdlock
wrlock、trywrlock
unlock
代码
效果:
可以看到,read线程占比较多,这也是读写锁的优势,r更多
条件变量
二级目录
二级目录
二级目录
信号量
二级目录
二级目录
二级目录
相关文章:

线程--线程同步
这里写目录标题 同步概念线程同步概念数据混乱原因 互斥量原理锁的注意事项1、cpu时间轮片2、建议锁总结 使用锁来管理线程同步问题产生主要函数init、destorylock、unlock代码注意事项(锁的粒度) try锁死锁出现原因图解 读写锁特性图解函数总览init、de…...

【QT】Qt窗口
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:QT 目录 👉🏻菜单栏设置👉🏻QToolBar练习 👉🏻QStausBar👉🏻Q…...

场外个股期权怎么给股票加杠杆?
今天期权懂带你了解场外个股期权怎么给股票加杠杆?场外期权交易通过向证券公司支付一定额度的股票期权费,然后买入大额的股票持仓,从而实现的杠杆交易。 买入看涨期权 操作:支付权利金购买看涨期权。 杠杆作用: 期…...

【Docker部署ELK】(7.15)
1、拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.0 docker pull docker.elastic.co/kibana/kibana:7.15.0 docker pull docker.elastic.co/logstash/logstash:7.15.02、配置文件(解压资源到D盘DOCKER目录下) 2.1 配置文件…...

UE4_后期处理_后期处理材质及后期处理体积一
后期处理效果 在渲染之前应用于整个渲染场景的效果。 后期处理效果(Post-processing effect)使美术师和设计师能够对影响颜色、色调映射、光照的属性和功能进行组合选择,从而定义场景的整体外观。要访问这些功能,可以将一种称为…...

【PyQt6 应用程序】基于QtDesigner做一个用户登录页面
在当今的软件开发领域,用户界面(UI)设计和后端编程是创建现代、互动应用程序的两大重要组成部分。尤其是在开发具有用户登录功能的应用程序时,不仅要注重外观和用户体验的设计,还要确保后端逻辑的安全性和可靠性。 本文将介绍如何使用PyQt6框架结合UI设计,实现一个简单而…...

Ollama—87.4k star 的开源大模型服务框架!!
这一年来,AI 发展的越来越快,大模型使用的门槛也越来越低,每个人都可以在自己的本地运行大模型。今天再给大家介绍一个最厉害的开源大模型服务框架——ollama。 项目介绍 Ollama 是一个开源的大语言模型(LLM)服务工具…...

MySQL表的操作与数据类型
目录 前言 一、表的操作 1.创建一个表 2.查看表的结构 3.修改表 4.删除一个表 二、 MySQL的数据类型 0.数据类型一览: 1.整数类型 2.位类型 3.小数类型 4.字符类型 前言 在MySQL库的操作一文中介绍了有关MySQL库的操作,本节要讲解的是由库管理的结构——…...

mysql把某一个字段的值中的aa,替换成bb
UPDATE my_table SET my_column REPLACE(my_column, aa, bb); 例 假设my_table表在替换前的数据如下: idmy_column1hello aa2world aa aa3no aa here 执行上述UPDATE语句后,my_table表的数据将变为: idmy_column1hello bb2world bb b…...

【系统架构设计师】原型模式详解
原型模式详解 1. 什么是原型模式? 原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制已有的对象来创建新的对象,而不是通过类实例化来创建新对象。通过这种方式,原型模式能够减少创建对象的开销,尤其是当对象的创建过程非常复杂或者耗费资源时。原型模…...

Spring @Async 深度解读:默认线程池执行器的配置与优化
在Spring中,Async注解用于异步执行方法。默认情况下,Async注解的任务是由一个线程池执行的。然而,这个默认的线程池是如何初始化的呢?本文将深入探讨这一过程,帮助你理解Spring异步任务背后的线程池执行器的初始化原理…...

手把手教你用护核纪元地心护核者用服务器开服联机
1、购买后登录服务器面板(百度莱卡云面板) 登录面板的信息在绿色的登陆面板按键下方,不是你的莱卡云账号 进入控制面板后会出现正在安装的界面,安装大约3分钟(如长时间处于安装中请联系我们的客服人员) 2、…...

Log4j 1.x如何升级到Log4j 2.x
Log4j 1.x升级到Log4j 2.x是一个涉及多个步骤的过程,主要包括删除旧版本、添加新版本依赖、配置新版本的配置文件等。以下是一个详细的升级步骤指南: 一、准备阶段 了解当前项目依赖: 检查项目中所有使用Log4j 1.x的地方,包括ja…...

CloudFlare问题与CDN问题
昨天将腾讯云的解析转移到Cloudflare中了,结果今天发现网站崩了,显示重定向次数过多,昨天估计是因为浏览器缓存,所以没有发现问题 问题一:强制HTTPS 当时看到CloudFlare的强制https时就想到了我的宝塔面板也开着强制h…...

[Linux]:文件(上)
✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. C语言文件操作 C语言文件操作接口如下,详情可参照——C语言文…...

flutter开发多端平台应用的探索 下 (跨模块、跨语言通信之平台通道)
前文 Flutter 是一个跨平台的开发框架,它允许开发者使用相同的代码库来构建 iOS、Android、Web 和桌面应用程序。 上文flutter开发多端平台应用的探索 上(基本操作)-CSDN博客列举了一些特定平台的case(桌面端菜单,鼠…...

第15-02章:理解Class类并获取Class实例
我的后端学习大纲 我的Java学习大纲 1、Java反射机制原理图: 源代码通过Javac编译得到字节码文件,当我执行到new一个对象的时候,字节码文件会通过ClassLoader被加载,然后得到一个Class类对象,存放在堆中,加…...

【Authing身份云-注册安全分析报告-无验证方式导致安全隐患】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…...

idea插件推荐之Cool Request
Cool Request是一款基于IDEA的HTTP调试工具,可以看成是轻量版的postman,它会自动扫描项目代码中所有API路径,按项目分组管理。一个类被定义为Controller且其中的方法被RequestMapping或者XXXMapping注解标注以后就会被扫描到。 对应方法左侧会…...

从卫星和飞机等不同传感器方面由QGIS 遥感分析
在地理信息科学 (GIS) 中,遥感是指从远处获取有关地球表面特征信息的行为。遥感数据是从许多不同的平台获取而来,包括卫星、飞机和具有许多不同传感器的固定仪器,包括光谱图像(相机)和激光雷达。最常见的遥感数据形式是卫星和航空图像。 为了充分实现这些照片的价值,需要…...

什么是AIGC?有哪些免费工具?
AIGC(AI Generated Content),即“人工智能生成内容”,是指通过人工智能技术自动生成各种类型的数字内容。AIGC 让机器能够根据输入的信息或数据生成符合人类需求的文本、图像、音频、视频等内容,极大提高了内容创作的效…...

腾讯云升级多个云存储解决方案 以智能化存储助力企业增长
9月6日,在腾讯数字生态大会腾讯云储存专场上,腾讯云升级多个存储解决方案:Data Platform 数据平台解决方案重磅发布,数据加速器 GooseFS、数据处理平台数据万象、日志服务 CLS、高性能并行文件存储 CFS Turbo 等多产品全新升级&am…...

Kubernetes 集群初步部署
Kubernetes 集群初步部署 目标 本手册旨在指导您在多台虚拟机上部署一个基础的Kubernetes集群,并安装必要的工具和组件。 准备工作 确保所有虚拟机已经准备好,并且具有足够的资源来运行Kubernetes集群。虚拟机操作系统版本一致,推荐使用R…...

从源码到成品:直播美颜SDK与主播美颜工具的开发全流程
本篇文章,小编将带你深入了解从源码到成品的开发全流程,探讨如何构建一个功能完善的直播美颜SDK与主播美颜工具。 一、需求分析与技术规划 在开发任何工具之前,需求分析是第一步。在美颜工具的开发过程中,需要明确以下几点&…...

AMD EPYC 9004服务器内存配置深度分析:为何全通道填充是关键?
在一次技术沟通中,客户询问在部署AMD EPYC 9004服务器时,是否应该完全填充内存通道? 考虑到AMD正在用5年的更新周期替换其AMD EPYC 7002 “Rome”和Cascade Lake一代的服务器,他们认为通过减少内存插槽的填充,可以节省…...

redis的事务与管道有什么不同?
Redis 的事务(MULTI/EXEC)和管道(PIPELINE)都是为了执行多条命令,但它们的工作原理和目标不同。以下是两者的详细对比。 1. Redis 事务 (MULTI/EXEC) 特点: 事务的本质:Redis 事务是一组命令的…...

Redis 配置
一、关系型数据库与非关系型数据库 1. 关系型数据库 关系型数据库是一种结构化数据库,基于关系模型(二维表格模型),适合记录数据。通过 SQL(结构化查询语言)进行数据的检索和操作。主流的关系型数据库包括…...

【Qt笔记】QTableWidget控件详解
目录 引言 一、QTableWidget的特点 二、QTableWidget基础 2.1 引入QTableWidget 2.2 基本属性 三、代码示例:初始化QTableWidget 四、编辑功能 4.1 设置单元格为只读 4.2 响应内容更改 五、选择模式 六、样式定制 七、与其他控件的交互 7.1 在单元格…...

高低压配电系统中电弧光的危害有多大?
摘要 故障电弧是一种常见的电气故障现象,尤其在配电系统中,可能对设备安全和电力供应造成严重影响。本文旨在探讨故障电弧对配电系统的危害,并提出相应的预防措施,以增强系统的可靠性和安全性。通过对故障电弧的形成机制、危害分…...

安宝特案例 | AR如何大幅提升IC封装厂检测效率?
前言:如何提升IC封装厂检测效率? 在现代电子产品的制造过程中,IC封装作为核心环节,涉及到复杂处理流程和严格质量检测。这是一家专注于IC封装的厂商,负责将来自IC制造商的晶圆进行保护、散热和导通处理。整个制程繁琐…...