进程的概念、组成、特征
概念
进程可以理解为程序的一次执行,同一个程序可以创建多个进程
组成
当进程被创建时,操作系统会为该进程分配一个唯一的PID(Process ID,进程ID),操作系统还会记录给进程分配的资源情况、运行状况等,这些信息都被保存在一个数据结构PCB中,也叫进程控制块
而进程的组成,则如下图:
其中,PCB由操作系统使用,程序段和数据段由进程使用
特征
- 动态性:进程是程序的一次执行过程,是动态地产生、变化和消亡的
- 并发性:内存中有多个进程实体,各进程可并发执行
- 独立性:进程是能独立运行、独立获得资源、独立接收调度的基本单位
- 异步性:各进程按各自的速度推进,操作系统提供进程同步机制来解决异步问题
- 结构性:每个进程都会配置一个PCB,结构上由三段组成(如上图)
进程的组织
因为操作系统中会存在很多进程,所以需要使用适当的方式将多个进程的PCB进行组织管理
链接方式
按照进程状态将PCB分为多个队列,操作系统持有指向各个队列的指针
索引方式
根据进程状态的不同,建立几张索引表,操作系统持有指向各个索引表的指针
进程的状态与转换
进程的状态有:
- 运行状态
- 就绪状态
- 阻塞状态
- 创建状态
- 终止状态
其中,运行、就绪、阻塞是三种最基本的状态
状态之间的转换: - 就绪态->运行态
- 运行态->就绪态
- 运行态->阻塞态
- 阻塞态->就绪态
创建态、就绪态
进程正在被创建时,它的状态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB;当进程创建完成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,等待cpu的执行
运行态
cpu正在运行的进程
阻塞态
在进程运行的过程中,可能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”
当CPU空闲时,又会选择另一个“就绪态”进程上CPU运行
终止态
一个进程可以执行 exit 系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。当终止进程的工作完成之后,这个进程就彻底消失了。
状态转换
在进程的PCB中,有一个变量 state 来表示进程的当前状态
进程控制
进程控制的主要功能是对系统中的所有进程实施有效的管理,它具有创建新进程、撤销已有进程、实现进程状态转换等功能;也就是说进程控制主要就是实现进程的状态转换
实现
通过原语来实现进程控制,原语的执行具有原子性,通过关中断指令和开中断指令这两个特权指令实现原子性
cpu执行关中断指令后,就不会对中断进行检查,所以具有原子性
原语
创建原语
- 申请空白PCB
- 为新进程分配所需资源
- 初始化PCB
- PCB插入就绪队列(创建态->就绪态)
终止原语
- 从PCB集合中找到终止进程的PCB
- 若进程正在运行,立即剥夺cpu使用权
- 终止其子进程
- 将该进程拥有的资源归还给父进程或操作系统
- 删除PCB
阻塞原语和唤醒原语
阻塞原语:
- 找到要阻塞的进程的PCB
- 保护进程运行现场,将PCB状态设置为阻塞态,暂时停止进程运行
- PCB插入相应的等待队列
唤醒原语: - 等待队列中找到PCB
- PCB从等待队列移除,设置为就绪态
- PCB插入就绪队列,等待被调度
切换原语
- 将运行环境信息存入PCB
- PCB移入相应队列
- 执行另一个进程,更新其PCB
- 根据PCB恢复新进程运行的环境
进程通信
多个进程之间产生数据交互。需要操作系统的支持
每个进程拥有的内存地址互相独立,进程之前不可以直接访问
共享存储
进程可以向操作系统申请共享存储区,这片区域其它进程也可以访问,为了避免原子性问题,各个进程对共享内存的访问是互斥的
基于存储区的共享:,操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统,这种共享方式速度很快,是一种高级通信方式
基于数据结构的共享:比如共享空间里只能放一个长度为10的数组,这种方式速度慢、限制多,是一种低级通信方式
消息传递
进程间的数据交换以格式化的消息为单位,进程通过操作系统提供的发送消息、接收消息
两个原语进行数据交换
又可划分为直接通信方式和间接通信方式:
直接通信方式:消息发送进程指明接收进程的ID
间接通信方式:消息先发送到中间实体(信箱)中
直接通信方式
进程p向进程q通信,进程q先创建包含消息头和消息体的消息节点,调用发送原语,指明进程q的PID,操作系统内核接受到后,将该消息放到进程q的消息队列中,进程q接收时,指定接收的进程PID,在进程q的pcb的消息队列中进行接收
👇
👇
👇
间接通信方式
进程p创建消息节点,发送给A信箱
进程q可以指定从哪个信箱接受消息
管道通信
一个管道的数据的传递只能是单向的,也就是半双工通信
若需要实现双向同时通信,需要设置两个管道
对管道的访问是互斥的,当管道写满时,写进程就会被阻塞,等待读进程将数据读走;当管道为空时,读进程就会被阻塞
管道就是在内存中开辟一个大小固定的内存缓冲区,进程q在读取数据的时候不能随机读取,只能按顺序依次读取,,管道区域类似于循环队列
管道的数据一旦被读取,就失效了,所以多个进程读取同一个管道时,可能会产生数据混乱;解决方案:1.一个管道允许多个写进程,读进程只能有一个;2.允许多个写进程,多个读进程,但系统会让各个读进程轮流从管道中读取(Linux)