进程的概念、组成、特征
![image-20230819154233868](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193456_image-20230819154233868.png)
程序是 静态的,存放在磁盘里的可执行文件,就是一系列的指令集合
进程(Process)是 动态的,是程序的一次执行过程。同一个程序多次执行会对应多个进程
操作系统如何区分各个进程
当进程被创建时,操作系统为该进程分配一个 唯一的、不重复的PID
PCB
操作系统要记录进程PID、进程所属用户ID(UID),还要记录给进程分配了哪些资源(内存,IO设备,正在使用哪些文件),还要记录进程的运行情况(CPU时间,磁盘使用情况,网络流量使用情况)
这些信息都保存在一个数据结构 PCB,进程控制块
![image-20230819193511287](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193513_image-20230819193511287.png)
进程的组成
![image-20230819152749471](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193519_image-20230819152749471.png)
![image-20230819153202636](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193521_image-20230819153202636.png)
- **程序段、数据段、PCB **三部分组成了进程实体(进程映像)
- 引入进程实体概念后可把进程定义为
- 进程是进程实体的 运行过程,是系统进行 资源分配和调度 的一个独立单位
- 调度指操作系统决定让这个进程上CPU运行
- 进程是进程实体的 运行过程,是系统进行 资源分配和调度 的一个独立单位
- PCB 是进程存在的唯一标志
进程的特征
- 动态性:进程是程序一次执行过程,是动态地产生、变化和消亡的
- 并发性:内存中有多个进程实体,各进程可并发执行
- 独立性:进程能独立运行、独立获得资源、独立接受调度的基本单位
- 在引入线程之后,进程不再是独立接受调度的基本单位
- 异步性:各进程按各自独立的、不可预知的速度向前推进,操作系统要提供 “进程同步机制” 解决异步问题
- 异步性会导致并发程序执行结果的不确定性
- 结构性:每个进程都会配置一个PCB。结构上看,进程由程序段、数据段、PCB组成。
进程的状态与转换
![image-20230819160845349](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193525_image-20230819160845349.png)
五个状态
![image-20230819160316325](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193529_image-20230819160316325.png)
- 创建态
- OS为进程分配资源、初始化PCB
- 就绪态
- 没有空闲CPU,暂时不能运行
- 运行态
- CPU空闲时,OS选择一个就绪进程,让它上处理机运行。CPU执行进程的指令序列
- OS给进程分配的时间片用完或CPU被更高优先级进程抢占,进程会进入 就绪态
- 阻塞态
- 进程运行过程中,可能会 请求等待某个事件的发生(如等待系统资源的分配、等待其他进程的响应)在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入 阻塞态。运行态到阻塞态是主动行为
- 当等待的事件发生后,变为 就绪态。阻塞态到就绪态是被动行为
- 终止态
- 进程可以执行exit系统调用,请求OS终止该进程,此时进程会进入 终止态,操作系统会让该进程下CPU,回收内存空间和该进程的PCB
状态转换
![image-20230819160105405](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193532_image-20230819160105405.png)
进程组织(队列)
大多数操作系统使用链接方式
![image-20230819160647380](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193535_image-20230819160647380.png)
![image-20230819160533146](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193537_image-20230819160533146.png)
进程组织(索引)
![image-20230819160616435](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193541_image-20230819160616435.png)
进程控制
![image-20230819193545815](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193548_image-20230819193545815.png)
无论哪个进程控制源于,要做的无非三类事情
- 更新PCB中的信息
- 修改进程状态、保存/恢复运行环境
- 将PCB插入合适的队列
- 分配/回收资源
原语
进程控制就是要实现进程状态转换,用 原语 实现
设一阻塞态进程等待的事件发生,则OS负责进程控制的内核程序至少需要做
- 设置该进程PCB的state
- 将该进程PCB从阻塞队列转移到就绪队列
原语的执行具有原子性,即执行过程只能一气呵成,期间不允许被中断
- 原语 使用关中断、开中断 两个特权指令实现原子性
正常情况下CPU每执行完一条指令都会例行检查是否有中断信号需要处理
CPU执行了 关中断指令 之后,就不再例行检查中断信号,直到执行 开中断指令 之后才会恢复检查
创建原语
![image-20230819193552418](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193554_image-20230819193552418.png)
撤销原语
![image-20230819172123372](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193558_image-20230819172123372.png)
阻塞原语和唤醒原语
![image-20230819172327994](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193601_image-20230819172327994.png)
切换原语
![image-20230819172522488](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193604_image-20230819172522488.png)
CPU会设置很多 寄存器 用于存放程序运行过程中所需的数据
![image-20230819172715779](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193606_image-20230819172715779.png)
![image-20230819173126473](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193607_image-20230819173126473.png)
当原来的进程再次投入运行时,可以通过PCB恢复它的运行环境
进程间通信
![image-20230819181918068](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193609_image-20230819181918068.png)
IPC指两个进程之间产生数据交互
需要OS内核支持
进程是分配系统资源的单位,因此各进程拥有的内存地址空间相互独立
为了保证安全,一个进程不能直接访问另一个进程的地址空间
共享存储
各个进程可以访问内存中的共享存储区,实现共享数据
![image-20230819174607073](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193612_image-20230819174607073.png)
基于存储区的共享
- OS在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。
基于数据结构的共享
- 共享空间里只能放一个长度为10的数组。共享方式速度慢、限制多,是一种低级通信方式。
消息传递
以格式化的消息为单位。进程通过操作系统提供的“发送消息/接收消息”两个 原语 进行数据交换。数据由 消息头、消息体 构成,消息头包括:发送进程ID、接受进程ID、消息长度等格式化的信息。
直接通信方式
![image-20230819193615742](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193617_image-20230819193615742.png)
- 发送进程要指明接收进程ID (指名道姓)
- 进程的PCB中有消息队列
- 进程P给进程Q发送消息,P在自己地址空间生成消息体msg,利用发送原语指明接收者Q和msg
- 进程Q的PCB的消息队列会添加msg(从用户空间复制到了内核空间)
- Q再利用接收原语指明接收P进程发来的msg
- OS内核会检查进程Q的消息队列,然后检查哪个msg是由P发过来的,再从OS内核区复制到Q的地址空间
间接通信方式
![image-20230819180233212](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193621_image-20230819180233212.png)
- 通过“信箱”间接地通信。因此又称“信箱通信方式”
- 信箱在OS内核地址空间中,作为一种中间实体
- P在自己地址空间生成消息体msg,进程P用发送原语指明发送给A信箱和msg(没有指明要发给Q)
- 信箱A会收到msg(从用户空间复制到了内核空间)
- Q再利用接收原语指明接收A信箱的msg
- 信箱A的msg从OS内核区复制到Q的地址空间
- 操作系统允许多个进程往同一个信箱发消息,也可以多个进程从同一个信箱里接收消息
管道通信
![image-20230819181049330](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193623_image-20230819181049330.png)
管道是一种特殊的共享文件,又名pipe文件。其实就是在内存中开辟一个大小固定的内存缓冲区。本质上是一个循环队列。
- 管道只能采用 半双工通信,某一时间段内只能实现单向的传输。如果要实现 全双工通信,则需要 设置两个管道
- 各进程要 互斥 地访问管道 (由操作系统实现)
- 当 管道写满时,写进程将阻塞,直到读进程将管道中的数据取走,即可唤醒写进程
- 当 管道读空时,读进程将阻塞,直到写进程往管道中写数据,即可唤醒读进程
- 管道中的数据一旦被读出,就彻底消失。因此,当多个进程读同一个管道时,可能会错乱。
- 解决方案:一个管道允许多个写进程,一个读进程 (应试类考试标准答案)
- 解决方案:多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读数据
![image-20230819182359181](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193625_image-20230819182359181.png)
线程
线程概念
传统进程只能串行地执行一系列程序。此时进程是程序执行流的最小单位
为此,引入了“线程”,线程可以理解为 “轻量级进程”。 线程是一个基本的CPU执行单元(处理机调度的基本单位),也是程序执行流的最小单位
进程之间可以并发,进程内的 各线程之间 也可以并发,从而进一步 提升了系统的并发度
进程不再作为CPU调度的基本单位,只作为除CPU之外的系统资源分配单元(打印机、内存地址空间等都是分配给进程的)
![image-20230819184129934](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193627_image-20230819184129934.png)
线程的属性
![image-20230819184340288](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193628_image-20230819184340288.png)
线程实现方式
![image-20230819192343695](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193632_image-20230819192343695.png)
用户级线程
![image-20230819184953466](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193635_image-20230819184953466.png)
- 线程的管理工作由 应用程序通过线程库完成
- 线程切换需要CPU变态吗 不需要,在用户态下就能完成线程切换工作
- 操作系统是否能意识到用户级线程的存在 意识不到,只能看到一个进程
- 只有用户才能感知到线程的存在
- 优点
- 用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
- 缺点
- 如果某一个用户级线程被阻塞,那么等同进程阻塞,并发度不高;多个线程不可在多核处理机上并行运行,进程只能分配一个核心。
内核级线程
![image-20230819190755339](./第二章.assets/image-20230819190755339.png)
- 线程的管理工作由 操作系统完成
- 线程切换需要CPU变态吗 需要操作系统介入
- 操作系统是否能意识到用户级线程的存在 意识得到
- 优点
- 当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
- 缺点
- 一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
多线程模型
在支持内核级线程的系统中,根据用户级线程和内核级线程的映射关系,可以划分为几种多线程模型
一对一模型
![image-20230819191403203](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193638_image-20230819191403203.png)
一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。
多对一模型
![image-20230819191313930](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193641_image-20230819191313930.png)
多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。
多对多模型
![image-20230819192259529](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193643_image-20230819192259529.png)
n个用户级进程映射到m个内核级进程。n>=m,每个用户进程对应m个内核级线程
线程的状态与转换
几乎与进程的状态与转换一样
![image-20230819192701213](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193645_image-20230819192701213.png)
线程的组织与控制
与进程的组织与控制类似
![image-20230819193307270](https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2023/08/20230819193647_image-20230819193307270.png)