36 线程概念

本章重点

1.了解线程概念,理解线程与进程的区别与联系
2.学会现充控制,线程创建,线程终止,线程等待
3.了解现场分离与线程安全
4.学会线程同步
5.学会使用互斥量,条件变量,posix信号量,以及读写锁
6.理解基于读写锁的读者写者问题

目录

1.linux中什么是线程
2.重新定义线程
3.线程的管理
4.重谈地址空间
5.怎么让线程执行不同的代码
6.线程比进程更轻量化
7.线程优点
8.线程缺点
9.线程异常
10.线程用途
11.进程vs线程

1. linux中什么是线程

基本概念

线程是进程内的一个执行分支,线程的执行粒度比进程要细
在这里插入图片描述

上面是进程的内存结构,地址空间是进程的资源窗口。当我们创建一个进程后,会拥有自己的pcb,地址空间和页表等,父子进程互相独立。如果这时我们创建一个进程,它拥有自己的pcb结构,代码和数据共用父进程的一部分,这样页表也可以用父进程的映射,不需要创建多余的内容就可以执行,把这种结构成为线程

在这里插入图片描述

linux实现方案

1.线程实在进程“内部”执行的,线程在进程的地址空间运行,任何执行流要执行就要有资源,地址空间是进程的资源窗口,线程的资源比如代码和数据就是来自于它的进程
2.线程的执行粒度要比进程更细,线程执行的是进程代码的一部分。cpu只有调度执行流的概念,不需要关心是进程还是线程

2. 重新定义概念

进程是承担分配系统资源的基本实体,线程是系统调度的基本单位

以前说过,进程=内核数据结构(task struct)+代码和数据,这种说法不冲突。创建进程就是创建一个pcb,执行流,创建页表的地址空间的映射,在物理内存开辟一个空间。这些东西都是要在内存中占空间的,所以说进程是分配资源的基本实体。线程是进程内部的一个执行流,执行流也是一种资源,os的调度在进程间不断切换,线程是进程中的一部分,也是os的基本单位

linux的执行流线程,是轻量级进程

如何理解以前的进程

os以进程为单位,给我们分配资源,我们以前的进程是只有一个执行流的情况,这种属于特殊情况,一般的进程都会有很多执行流

3. 线程的管理

进程中有很多线程,是1:n的关系。线程需要cpu调度运行,线程有自己的资源那么就必须管理起来。有的会给线程用一个tcb的结构来管理,在linux中,考虑到线程和进程的结构并没有差太多,所以复用了进程的pcb结构模拟线程。这样更方便也更容易管理,由于pcb的基础上描述现成,所以也更稳定

4. 重谈地址空间

进程是承担资源分配的基本单位,线程又是进程的一部分内容。具体虚拟地址到物理地址是怎么转换的?
在这里插入图片描述

物理内存是分为很多块的,以4kb为cpu访问的基本单位,整体用一个数组来管理。32位的机器一个地址是32位的,页表保存的是虚拟地址到物理的映射关系,虚拟地址空间是4个G,也就是232,如果将页表看做一行有虚拟地址4字节,物理地址4字节,权限位2字节,看为10字节,页表被写满的情况就需要232 * 10的大小才能存储,这个结果是很大的,更不用说有很多进程,由其他内容,所以不可能这样存储

在这里插入图片描述

首先,将一个32位的地址分为10+10+12位三部分
在这里插入图片描述

页表分为两级页表,首先将地址的第一个10位转换为十进制,在第一个页表中索引下标,一级页表总共存1024个地址,对应了二级目录。由一级页表索引到二级页表的地址,然后将第二个10位转换为十进制,在二级页表索引下标,就能找到页框的起始地址,二级目录还包括权限之类的字段。最后一个12位刚好是4k的大小,转换为十进制,作为页框起始的地址的偏移量,就对应了物理内存中的地址。偏移量不会超过页框的大小

二级页表一个地址4字节,总共有1024个地址,就是4kb,一级页表可以存1024个二级页表的地址,也就是4*1024=4mb。用户空间只有3G,而且实际上一个进程基本不会占完所有大小,甚至只占用一小部分。二级页表大部分是不全的

有的页框的大小是4mb,最终的页表会更小,大页式内存

地址偏移

最后索引后只拿到了一个地址,内置类型取地址都是最低的地址,根据偏移读值。cpu怎么知道读取几个字节?类型的本质,是给cpu看的,cpu内置是能识别知道需要读几个字节的,比如有些命令是word,dword等。类的本质也是一堆内置类型的集合,空类也是有大小,才能找到它。所以起始地址+类型=起始地址+偏移量,x86的特点。

页表访问如果越界了,CR2寄存器保存的越界等其他原因造成的异常或缺页中断的地址。这样缺页中断加载后,就能把这个地址拿出来访问。

线程分配资源,本质就是分配地址空间范围

5. 怎么让线程执行不同的代码

函数地址是天然不一样,没交集的,只需要将不同函数地址交给不同的线程运行

6. 线程比进程更轻量化

从整个生命周期看
a.创建和释放更轻量化(生死)
b.切换更轻量化(运行)

线程在切换的时候,一定有自己的上下文数据要切换,页表和地址空间不需要切换,所以更少一点。cpu保存和恢复的数据更少,这里只是几个寄存器的多少。cpu里还有一个硬件级catch缓存,占的比较大。会把接下来要读取的部分代码都加载到里面,这样可以考虑到让运行更快,这部分数据叫做热数据。切换线程的时候,这部分是可以继续用的,线程在运行的时候,进程的时间片也在走,当进程切换的时候,catch数据需要重新缓存,由冷变热

一个进程的时间片是平均划分给线程,并不能创建一个线程就会增加时间片。怎么知道切换的是进程和线程,pcb里是需要标识的。将刚启动的线程叫父进程,其他线程叫新线程。os可以知道是进程还是线程的时间片用完了,主次线程也可以区分
在这里插入图片描述

7. 线程的优点

创建一个新线程的代价要比创建一个新线程小的多
与进程之间的切换相比,线程之间的切换需要操作系统做的工作少得多
线程占用的资源要比进程少得多
能充分利用多处理器的可并行数量
在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现。并不是越多越好,由多少个cpu创建多少个线程最好
I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作

8. 线程的缺点

  • 性能损失
    一个很少被外部事件阻塞的计算密集型线程往往无法与共它线程共享同一个处理器如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变
  • 健壮性降低
    编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的
  • 缺乏访问控制
    进程是访问控制的基本粒度,在一个线程中调用某些os函数会对整个进程造成影响
  • 编程难度提高
    编写与调试一个多线程程序比单线程程序困难

9. 线程异常

单个线程如果出现除零,野指针问题导致线程崩溃,进程也会随着崩溃
线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也就随即退出

10. 线程用途

合理的使用多线程,能提高cpu密集型程序的执行效率
合理的使用多线程,能提高IO密集型程序的用户体验(如一边写代码一边下载开发工具,就是多线程)

11. 进程vs线程

进程是资源分配的基本单位
线程是调度的基本单位
线程共享进程数据,但也拥有自己的一部分数据

  • 线程ID
  • 一组寄存器
  • errno
  • 信号屏蔽字
  • 调度优先级

进程的多个线程共享统一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个去哪聚变量,在个线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:

  • 文件描述符表
  • 每种信号的处理方式(SIG_IGN、SIG_DFL或者自定义的信号处理函数)
  • 当前工作目录
  • 用户id和组id

线程哪部分独占,独立的上下文和独立的栈结构,前者保证线程独立调度,后者保证多个执行流不会错乱

线程和线程的关系如下图:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

cnpm安装

npm install -g cnpm --registryhttps://registry.npmmirror.com # 注册模块镜像 npm set registry https://registry.npmmirror.com // node-gyp 编译依赖的 node 源码镜像 npm set disturl https://npmmirror.com/dist // 清空缓存 npm cache clean --force // 安装c…

Linux中的yum和gcc/g++

一、快速认识yum(简单介绍) 在Linux中,我们也要进行工具/指令/程序、安装、检查、卸载等等,需要使用到yum 在Linux中安装软件的方式: 源代码安装——交叉编译的工作rpm包直接安装yum/apt-get yum:yum是我们Linux预…

Androd SharedPreferences 存取key-value键值对的用法小结

文章目录 一、存储数据二、读取数据三、删除数据3.1 删除指定KEY的数据3.2 删除所有数据 四、测试4.1 查找数据文件4.2 查看数据的存储 在开发一个简单Launcher,点击APP按钮后,如无APP绑定,则弹出一个APP选择列表,选择后进行绑定&…

STL--string详解

STL基本内容 string是什么 string实质上是一个对象 string可看作一个串,类似字符数组 可以扩容,可以增删查改 可用下表访问操作符[]引用,修改某值 构造函数 默认构造 拷贝构造:参数为(string 或 char*) 求string对象的长度不…

AI预测体彩排列3第2套算法实战化测试第5弹2024年4月27日第5次测试

今天继续进行新算法的测试,今天是第5次测试。好了,废话不多说了,直接上图上结果。 2024年4月27日体彩排3预测结果 6码定位方案如下: 百位:6、2、1、7、8、9 十位:8、9、4、3、1、0 个位:3、7、8…

【C++】学习笔记——类和对象5

文章目录 二、类和对象14. 日期类的实现15. const成员16. 取地址重载17. 再谈构造函数初始化列表 18. explicit关键字19. static成员 未完待续 二、类和对象 14. 日期类的实现 上一篇我们已经大致将日期类的重要功能都给实现了,这节将会对日期类进行完善&#xff…

在Windows10上安全弹出U盘的三种方法,总有一种适合你

序言 为了避免数据丢失,你有必要学习如何在使用完外部硬盘或U盘后安全地将其从计算机中取出。如果在断开U盘之前不弹出,你可能会面临数据损坏的问题。所以不要懒惰。那么,如何从计算机中弹出外部硬盘驱动器或U盘?看看这里。这篇文…

强化训练:day5(游游的you、腐烂的苹果、孩子们的游戏(圆圈中最后剩下的数)

文章目录 前言1. 游游的you1.1 题目描述1.2 解题思路1.3 代码实现 2. 腐烂的苹果2.1 题目描述2.2 解题思路2.3 代码实现 3. 孩子们的游戏(圆圈中最后剩下的数)3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 本章内容:游游的you、腐烂的苹果、孩子们的游戏(圆圈中…

【03】JAVASE-分支语句【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture:波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。…

Redis 服务等过期策略和内存淘汰策略解析

redis服务是基于内存运行的,所以很多数据都存放在内存中,但是内存又不是无限的,所以redis就引出了key的过期和淘汰策略。 一、Redis的过期策略: 我们在set key的时候,可以给它设置一个过期时间,比如expire …

Autosar MCAL-RH850P1HC Fls配置

文章目录 FlsFlsGeneralFlsAcLoadOnJobStartFlsBaseAddressFlsBlankCheckApiFlsCancelApiFlsCompareApiFlsCopySupportedFlsCriticalSectionProtectionFlsDevErrorDetectFlsDeviceNameFlsDriverIndexFlsFaciEccCheckFlsGetJobResultApiFlsGetStatusApiFlsLoopCountFlsReadImmed…

(待更)DRF: 序列化器、View、APIView、GenericAPIView、Mixin、ViewSet、ModelViewSet的源码解析

前言:还没有整理,后续有时间再整理,目前只是个人思路,文章较乱。 注意路径匹配的“/” 我们的url里面加了“/”,但是用apifox等非浏览器的工具发起请求时没有加“/”,而且还不是get请求,那么这…

大语言模型在研究领域的应用——信息检索中的大语言模型

信息检索中的大语言模型 大语言模型提升信息检索任务利用大语言模型进行信息检索大语言模型增强的信息检索模型. 检索增强的大语言模型输入优化策略.指令微调策略.预训练策略. 总结应用建议未来方向 大语言模型对于传统信息检索技术与应用范式带来了重要影响。这两者在技术路径…

【加密周报】中美下周有“大事”发生!准备联手引爆比特币大行情?美国大型养老基金和梅隆银行已持有比特币ETF!

自减半之后,比特币便进入了横盘状态,始终在6-6.5万美元价格区间震荡。4月24日,香港证监会官网正式公示虚拟资产现货ETF获批名单,华夏(香港)、嘉实国际、博时国际旗下相关产品均在其列,并计划将于…

K8s 使用 Ceph RBD 作为后端存储(静态供给、动态供给)

一、K8s 使用 Ceph RBD Ceph RBD(Rados Block Device)是 Ceph 存储集群中的一个重要组件,它提供了块级别的存储访问。RBD 允许用户创建虚拟块设备,并将其映射到客户端系统中,就像本地磁盘一样使用。 首先所有 k8s 节…

【算法学习】线段树基础版

一 线段树 1.概念 线段树可以理解为一个二叉树,如果是利用线段树求区间的和,那么每个结点的权值维护的是结点所维护区间的和,再将该区间一分为二,分别交由左右儿子维护。 拿区间1 - 4的和来举例子, 根结点维护的是区…

嵌入式Linux学习——Ubantu初体验

Ubuntu 和Windows 的最大差别 Windows中的每一个分区都对应着一个盘符,盘符下可以存放目录与文件,而在Ubantu中没有盘符的概念,只有目录结构。实际上不同的目录可能挂载在不同的分区之下,如果想要查看当前目录位于磁盘的哪个分区…

IDEA:运行 Tomcat 报错 “1099”

1、报错的结果 报错 就很明显啊 localhost:1099 端口号被使用了 2、报错原因 tomcat的端口已经被使用,与运行的起了冲突。强制结束项目,但端口号没有被释放短时间内频繁运行tomcat服务器。 3、解决方法 win R 输入 cmd 打开命令框 黑窗口输…

个人学习-前端相关(2):ECMAScript 6-箭头函数、rest、spread

ES6的箭头函数 ES6允许使用箭头函数,语法类似java中的lambda表达式 let fun1 function(){} //普通的函数声明 let fun2 ()>{} //箭头函数声明 let fun3 (x) >{return x1} let fun4 x >{return x1} //参数列表中有且只有一个参数,()可…

纯血鸿蒙APP实战开发——预渲染实现Web页面瞬开效果

介绍 为了便于大家在使用本案例集时能够更详细的了解各个案例,本案例基于Web预渲染实现了案例介绍功能,即应用右下角的问号icon。 效果图预览 使用说明 因为直接加载的线上README,因此本功能需联网使用点击icon,即会弹出对应案…