线程--线程同步

news2025/2/25 11:31:44

这里写目录标题

  • 同步概念
    • 线程同步概念
    • 数据混乱原因
  • 互斥量
    • 原理
    • 锁的注意事项
      • 1、cpu时间轮片
      • 2、建议锁
      • 总结
    • 使用锁来管理线程同步
      • 问题产生
      • 主要函数
      • init、destory
      • lock、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、在每个线程访问共享区的前后进行加锁和解锁:
子线程:
在这里插入图片描述
主线程:
在这里插入图片描述

效果:
在这里插入图片描述每个线程的数据被完整的加入到了共享区

注意事项

假如说,我们把解锁的操作移到循环步的最后:
在这里插入图片描述
在这里插入图片描述
可以看到,主线程和子线程都使用加锁和解锁把原来的所有代码包裹起来,这样结构上确实很清晰

但是:
在这里插入图片描述
在这里插入图片描述
可以看到,最终要么只执行主线程,要么只执行子线程

原因:
由于线程在解锁之后立马就进入下一个循环,使得解锁之后该线程又拿到了锁,所以,就会一直保持一个线程,另一个线程无法拿到锁

所以:
在这里插入图片描述
我们的加锁和解锁操作,只在访问共享区的前后,立即执行,锁尽量只包含访问共享区的代码部分

补充:
在这里插入图片描述
可以将互斥锁的操作看成整数,
初始化时,值为1,表示当前锁可以被拿取并使用
之后,加锁时,–,那么值变为0,表示已经加锁,锁目前被占用,无法使用,其他线程就无法使用锁,无法访问共享区了
最后,解锁时,++,值变回1,表示再次可以使用

条件变量

二级目录

二级目录

二级目录

信号量

二级目录

二级目录

二级目录

一级目录

二级目录

二级目录

二级目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131204.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法:数字化系统的智慧核心

在当今快速发展的数字化时代,算法在数字化系统中扮演着至关重要的角色。从数字孪生系统到物联网应用,算法不仅是技术进步的推动力,更是实现智能化、自动化的核心。本文将探讨数字化系统中算法的重要性,以及它们是如何被实现和集成…

spring容器创建bean过程中使用到的几个factory

文章目录 前述BeanFactoryFactoryBeanObjectFactory 前述 spring我们可以理解为一个帮我们管理bean的容器,使用spring框架之前创建bean都是通过new的方式,使用spring框架之后, 我们只需要告诉spring框架我们有那些bean,它会帮我们…

Linux:命令行参数

目录 一、命令行参数是什么? 二、命令行参数作用 三、命令行参数如何传递给main函数? 一、命令行参数是什么? C语言中的main函数,我们发现既可以带参数,也可以不带参数。带参数的main函数如下: 参数为一…

Matplotlib - Statistical Distribution作图

1. 前言 在数据分析和统计学中,绘制统计分布图是非常重要的,因为它帮助我们直观地理解数据的特性,并为进一步的分析提供基础。统计分布图能够揭示数据集的结构、趋势、集中趋势和离散程度等信息,从而使我们更容易做出合理的假设、…

监控系统添加vcenter上的esxi主机

监控系统的软件选择: 监控系统要求 快速搭建 能快捷地添加vcenter上的主机(esxi) 能实现动态添加主机监控 可供选择的监控软件 Prometheus vmware_exporter添加 vcenter及esxi监控,报奇怪的错误,解决时间比较长&a…

高阶数据结构之哈希表基础讲解与模拟实现

程序猿的读书历程:x语言入门—>x语言应用实践—>x语言高阶编程—>x语言的科学与艺术—>编程之美—>编程之道—>编程之禅—>颈椎病康复指南。 前言: 哈希表(Hash Table)是一种高效的键值对存储数据结构&…

C++(进阶) ─── 继承

目录 1.继承的概念及定义 1.1继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6. 继承与静态成员 7.复杂的菱形继承及菱形虚拟继承 8.继…

ARCGIS PRO DSK MapTool

MapTool用于自定义地图操作工具,使用户能够在ArcGIS Pro中执行特定的地图交互操作。添加 打开MapTool1.vb文件,可以看到系统已经放出MapTool1类: Public Sub New()将 IsSketchTool 设置为 true 以使此属性生效IsSketchTool TrueSketchTyp…

秋招测评为什么有行测题型?有没有训练题库?

为什么有行测题型,那这就得看看行测题型的作用了。 1、行测题可以比较全面评估应聘者的基本素质,包括数学能力、语言能力、逻辑思维能力等。这些能力是从事各类职业所必需的基本能力,对于判断应聘者的学习潜力和工作效率具有重要意义。 2、…

MySQL基于GTID同步模式搭建主从复制

系列文章目录 rpmbuild构建mysql5.7.42版本的rpm包 文章目录 系列文章目录一、mysql-5.7.42RPM包构建二、同步模式分类介绍1.异步同步模式2.半同步模式2.1.实现半同步操作流程2.2.半同步问题总结2.3.半同步一致性2.4.异步与半同步对比 3.GTID同步 三、GTID同步介绍1.gtid介绍2…

如何准备多台虚拟机并配置集群化软件

在搭建集群化软件的过程中,首先需要准备好多台Linux服务器。本文将详细介绍如何使用VMware提供的克隆功能来准备多台虚拟机,并进行必要的配置以实现集群化软件的部署。 1. 准备多台虚拟机 安装集群化软件,首要条件就是要有多台Linux服务器可…

nvm无法下载npm的问题

1、问题 执行 nvm install 14.21.3 命令,node可以正常下载成功,npm下载失败 2、nvm配置信息 …/nvm/settings.txt root: D:\soft\nvm path: D:\soft\nodejs node_mirror: npmmirror.com/mirrors/node/ npm_mirror: registry.npmmirror.com/mirrors/…

Java面试篇基础部分-Java内部类介绍

首先需要了解什么是内部类,内部类就是定义在类的内部的类称为内部类,内部类可以根据不同的定义方式分为静态内部类、成员内部类、局部内部类和匿名内部类。 静态内部类 定义在类体内部的通过static关键字修饰的类,被称为静态内部类。静态内部类可以访问外部类的静态变量和…

BEV学习---LSS-3--(体素坐标系及各种坐标系的理解)

1、体素坐标系 如下两个链接,详细介绍了对体素坐标系的理解: 体素坐标(voxel_coors)在mmdetection3d中的理解_体素坐标系-CSDN博客 3D目标检测中坐标系详解_点云用的什么坐标系-CSDN博客 2、自动驾驶中各种坐标系的定义及相互转换 【KnowledgeBase】…

lamp和nginx的搭建

lamp搭建 下载需要用到的 yum install php yum install php-mysql yum install php-mbstring 进入到html路径下,将文件复制到该路径 解压文件 将文件夹里的内容都复制到html下 在配置文件中添加页面index.php 此时打开网页提示需添加可写权限 但因为直接添加不…

Java实现发送邮件如何配置SMTP和认证信息?

Java实现发送邮件的关键要点?Java怎么实现邮件发送? Java作为一种强大的编程语言,提供了丰富的库和工具来实现邮件发送功能。AokSend将详细介绍如何在Java中配置SMTP服务器和认证信息,以实现邮件发送功能。 Java实现发送邮件&am…

企业级镜像容器的访问控制

为保障镜像制品及企业版实例安全,需要配置公网的访问控制策略,以限制通过公网访问企业版实例。 ps: 本功能只能在企业版实例使用,对于个人版实例不支持使用此功能。 操作步骤 1、登录容器镜像控制台 ; 2、在顶部菜单栏&#xf…

鱼类检测-目标检测数据集(包括VOC格式、YOLO格式)

鱼类检测-目标检测数据集(包括VOC格式、YOLO格式) 数据集: 链接:https://pan.baidu.com/s/1B4o8IgOmAWeQJDWpJWxqXg?pwdjaco 提取码:jaco 数据集信息介绍: 共有 2848 张图像和一一对应的标注文件 标注文…

[图论]街道赛跑

题目描述 图一表示一次街道赛跑的跑道。可以看出有一些路口(用 0 0 0 到 N N N 的整数标号),和连接这些路口的箭头。路口 0 0 0 是跑道的起点,路口 N N N 是跑道的终点。箭头表示单行道。运动员们可以顺着街道从一个路口移动到…

自测的重要性

1、把debug一遍,看看每一步变量值的变化都符合预期 2、核对需求文档,看看是不是自己的逻辑跟需求都是匹配的,有没有遗漏的细节 3、有时候配合接口的使用方去做点假数据,也是发现自己接口漏洞的好机会 发现了sql少写了个条件、发…