一、进程的基本概念
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
在早期的计算机中只支持单道程序,即在一个时间段内,计算机中只能有一个程序在运行,此时CPU、内存等部件都为这一个程序服务。
程序段:用来存放程序本身的代码
数据段:程序运行过程中处理的数据放在其中(如变量)
无疑,资源利用率非常低下,在引入多道程序技术后,一段时间内计算机中可以有多个程序在运行。内存中同时放入多道程序,各个程序的代码、运算数据存放的位置不同,操作系统如何能找到呢?
进而为了方便操作系统管理,完成多个程序的并发执行,引入了进程的概念。
进程实体
系统为每个运行的程序配置一个数据结构,称为进程控制块(PCB),用来记录进程的各种信息。而PCB + 程序段 + 数据段 = 进程实体。一般我们将进程实体简称为进程。
特征
- 动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
- 并发性:任何进程都可以同其他进程一起并发执行。
- 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。
- 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。
PCB的组织方式
在多道程序技术情况下,系统中往往会存在成百上千个PCB,它们是如何组织的呢?
- 链接方式
- 索引方式
链接方式:按进程状态将PCB分为多个队列
- 运行指针:指向当前正在运行的PCB,同一时刻只有一个。
- 就绪状态指针:指向就绪状态的PCB,按照优先级链式存储。
如PCB1-->PCB3-->PCB2-->PCB5 ...
- 阻塞状态指针:指向阻塞状态的PCB,同样是链式存储。
索引方式
与链式存储方式不同的是,索引方式在就绪状态和阻塞状态上有所不同,索引方式的处理方法是建立一个索引表。类似Java中的数组。
类似这样:
表中存放的都是地址,用来记录PCB所在位置。
二、进程五大基本状态
说明:进程的状态可有七种,这里先介绍五种,在后续的操作系统博客中再对另外两种状态做介绍。
图示:
- 创建态:进程在创建时需要申请一个空白PCB,向其中填写控制和管理进程的信息,完成资源分配。如果创建工作无法完成,比如资源无法满足,就无法被调度运行,把此时进程所处状态称为创建状态
- 就绪态:进程已经准备好,已分配到所需资源,只要分配到CPU就能够立即运行
- 运行态:进程处于就绪状态被调度后,进程进入执行状态
- 阻塞态:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用
- 终止态:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行
三、进程控制
什么是进程控制?
从进程创建到死亡,对其全部的行为进行控制。有创建进程、阻塞进程、唤醒进程、撤销进程等行为。
创建进程:
- 创建一个空白PCB
- 获得并赋予进程标识符ID并分配空间
- 初始化PCB
- 把进程插入到相应的进程队列,一般放到就绪队列中
撤销进程:
- 在PCB队列中找到要撤销进程的PCB
- 获取该进程的状态
- 若该进程处于运行态,则立即终止该进程,将CPU分配给其他进程
- 释放进程占有的资源,移除PCB
阻塞进程:
- 找到要阻塞进程对应的PCB
- 保护进程运行现场,将PCB状态信息设置为“阻塞态”,暂时停止进程运行
- 将PCB插入相应事件的等待队列
唤醒进程:
- 在事件等待队列中找到PCB
- 将PCB从等待队列移除,设置进程为就绪态
- 将PCB插入就绪队列,等待被调度
进程控制会导致进程状态的改变,无论哪个原语,要做的无非就是三件事:
- 更新PCB信息
- 所有的进程控制原语一定会修改进程状态标志
- 进程状态转换之前要保存其运行环境
- 进程开始之前要恢复其运行环境
- 进程的阻塞和唤醒一定是成对存在的,进程因为什么事件被阻塞,就会被什么事件唤醒
- 将PCB插入到合适的队列
- 分配/回收资源
进程控制是由原语来实现的,我们可以做一个假设:如果某次进程状态转换成功,此时一个由于某个中断指令介入导致PCB没有完成修改,就会导致PCB所在位置与进程状态不符,可能会导致系统错误,为此,进程控制才由原语进行实现。
原语的特征:不可中断,一气呵成!
在执行原语指令之前会进行一个关中断操作,在此期间,如果有一个外部中断指令,就会被阻挡,进而保证了原语的执行不会被中断,执行完毕后,再进行一个开中断操作,此时再有外部中断指令才会被处理。