目录
1、什么是前驱图?
2、进程的定义和描述
(1)什么是进程?
(2)进程的基本状态及转换
(3)挂起操作和进程状态的转换
3、进程管理中的数据结构
(1)进程控制块 PCB 的作用
(2)进程控制块 PCB 中的信息
(3)PCB 的组织方式
3、进程的控制
(1)操作系统内核
(2)进程的创建
(3)进程的终止
(4)进程的阻塞与唤醒
(5)进程的挂起与激活
1、什么是前驱图?
前趋图(Precedence Graph),是指一个有向无循环图,可记为DAG(DirectedAcyclic Graph),它用于描述进程之间执行的先后顺序。// 描述工具
注意,前趋图中是不允许有循环的,否则必然会产生不可能实现的前趋关系。如图 2-1(b) 所示的前趋关系中就存在着循环。它一方面要求在 S3 开始执行之前 S2 必须完成,另一方面又要求在 S2 开始执行之前,S3 必须完成。显然,这种关系是不可能实现的。// 前驱图不允许循环
程序顺序执行时的三个特征:(1)顺序性、(2)封闭性、(3)可再现性 // 易于调试
程序并发执行时的三个特征:(1)间断性、(2)失去封闭性、(3)不可再现性
2、进程的定义和描述
(1)什么是进程?
进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。
为了使参与并发执行的每个程序都能独立地运行,在操作系统中为之配置一个专门的数据结构,称为进程控制块(Process Control Block,PCB)。系统利用 PCB 来描述进程的基本情况和活动过程,进而控制和管理进程。这样,由程序段、相关的数据段和 PCB 三部分便构成了进程实体。一般情况下,我们把进程实体就简称为进程,例如,所谓创建进程,实质上是创建进程实体中的 PCB,而撤消进程,实质上是撤消进程的 PCB。
(2)进程的基本状态及转换
1)进程的三种基本状态
一般而言,每一个进程至少应处于以下三种基本状态之一:// 注意,这里只是基本状态,不同操作系统还有更多的其他状态,这里相当于给了一个状态的模型
- 就绪(Ready)状态:该状态下,进程已分配到除 CPU 以外的所有必要资源后,只要再获得 CPU,便可立即执行。如果系统中有许多处于就绪状态的进程,通常将它们按一定的策略(如优先级策略)排成一个队列,称该队列为就绪队列。// 给CPU就可运行
- 执行(Running)状态:这是指进程已获得 CPU,其程序正在执行的状态。对任何一个时刻而言,在单处理机系统中,只有一个进程处于执行状态, 而在多处理机系统中,则可能有多个进程处于执行状态。
- 阻塞(Block)状态:这是指正在执行的进程由于发生某事件(如 IO 请求申请缓冲区失败等)暂时无法继续执行时的状态,即进程的执行受到阻塞。此时引起进程调度,OS把处理机分配给另一个就绪进程,而让受阻进程处于暂停状态,一般将这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。通常系统将处于阻塞状态的进程也排成一个队列,称该队列为阻塞队列。实际上,在较大的系统中,为了减少队列操作的开销,提高系统效率,根据阻塞原因的不同,会设置多个阻塞队列。// 给CPU也不能运行
// 操作进程实质上就是操作 PCB,CPU 对进程的调度实质上就是把 PCB 从一个队列放置到另一个队列的过程
下图是一个进程在队列中的转移图:
2)三种基本状态的转换
就绪状态的进程,在调度程序为之分配了 CPU 之后便可执行,相应地,其状态就由就绪态转变为执行态;// 就绪 ->获取CPU -> 执行
正在执行的进程如果因分配给它的时间片已完而被剥夺 CPU 暂停执行时,其状态便由执行转为就绪;如果因发生某事件,致使当前进程的执行受阻(例如进程访问某临界资源,而该资源正被其它进程访问时),使之无法继续执行,则该进程状态将由执行转变为阻塞。
下图出了进程的三种基本状态,以及各状态之间的转换关系。// 就绪是不能转为阻塞的,因为还没执行,所以并不知道缺少什么条件
3)创建状态和终止状态
创建状态:创建一个进程是个很复杂的过程,一般要通过多个步骤才能完成:
- 如首先由进程申请一个空白 PCB,并向 PCB 中填写用于控制和管理进程的信息
- 然后为该进程分配运行时所必须的资源
- 最后,把该进程转入就绪状态并插入就绪队列之中
但如果进程所需的资源尚不能得到满足,比如系统尚无足够的内存使进程无法装入其中,此时创建工作尚未完成,进程不能被调度运行,于是把此时进程所处的状态称为创建状态。// 申请PCB -> 分配资源 -> 转入就绪队列
终止状态:进程的终止有两个步骤:// 清除 PCB
- 首先,是等待操作系统进行善后处理
- 最后将其 PCB 清零,并将 PCB 空间返还系统
当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结,它将进入终止状态。// 进入终止状态的场景
进入终止态的进程以后不能再执行,但在操作系统中依然保留一个记录,其中保存状态码和一些计时统计数据,供其他进程收集。一旦其他进程完成了对其信息的提取之后,操作系统将删除该进程,即将其 PCB 清零,并将该空白 PCB 返还系统。// PCB 清零有一个过程
下图给出了增加了创建状态和终止状态后进程的五种状态及转换关系图
(3)挂起操作和进程状态的转换
进程除了就绪、执行和阻塞三种最基本的状态外,为了系统和用户观察和分析进程的需要,还引入了一个对进程的重要操作——挂起操作。当该操作作用于某个进程时,该进程将被挂起,意味着此时该进程处于静止状态。如果进程正在执行,它将暂停执行。若原本处于就绪状态,则该进程此时暂不接受调度。与挂起操作对应的操作是激活操作(挂起原语 Suspend 和 激活原语 Active)。
3、进程管理中的数据结构
在计算机系统中,对于每个资源和每个进程都设置了一个数据结构,用于表征其实体。我们称之为资源信息表或进程信息表,其中包含了资源或进程的标识、描述、状态等信息以及一批指针。// 对资源的表示都是通过数据结构来进行的,PCB 就是一个比较复杂的数据结构
通过这些指针,可以将同类资源或进程的信息表,或者同一进程所占用的资源信息表分类链接成不同的队列,便于操作系统进行查找。
如下图所示,OS 管理的这些数据结构一般分为以下四类:内存表、设备表、文件表和用于进程管理的进程表,通常进程表又被称为进程控制块 PCB。
(1)进程控制块 PCB 的作用
PCB 作为进程实体的一部分,记录了操作系统所需的,用于描述进程的当前情况以及管理进程运行的全部信息,是操作系统中最重要的记录型数据结构。// 记录进程的所有信息
PCB的作用:使一个在多道程序环境下不能独立运行的程序(含数据)成为一个能独立运行的基本单位,一个能与其他进程并发执行的进程。具体阐述如下:
- 作为独立运行基本单位的标志。PCB 是进程存在于系统中的唯一标志。
- 能实现间断性运行方式。在多道程序环境下,程序是采用停停走走间断性的运行方式运行的。系统可将 CPU 现场信息保存在被中断进程的 PCB 中,供该进程再次被调度执行时恢复 CPU 现场时使用。
- 提供进程管理所需要的信息。当调度程序调度到某进程运行时,只能根据该进程的 PCB 找到进程所需的全部资源。在进程的整个生命期中,操作系统总是根据 PCB 实施对进程的控制和管理。
- 提供进程调度所需要的信息。在 PCB 中保留了进程所有的状态信息。// 就绪 -> 执行
- 实现与其它进程的同步与通信。在 PCB 中具有用于实现进程通信的区域或通信队列指针、用于同步的信号量等。
(2)进程控制块 PCB 中的信息
在进程控制块中,主要包括下述四个方面的信息。
1)进程标识符
进程标识符用于唯一地标识一个进程。
一个进程通常有两种标识符:
- 外部标识符:主要是为了方便用户(进程)对进程的访问,它由创建者提供的,通常由字母、数字组成。
- 内部标识符:主要是为了方便系统对进程的使用,内部标识符赋予每一个进程一个唯一的数字标识符,它通常是一个进程的序号。
2)处理机状态/CPU状态
处理机状态信息也称为处理机的上下文,主要是由处理机的各种寄存器中的内容组成的。
这些寄存器包括:(1)通用寄存器(2)指令计数器(3)程序状态字 PSW(4)用户栈指针等。当进程被切换时,处理机状态信息都必须保存在相应的 PCB 中,以便在该进程重新执行时能再从断点继续执行。// CPU上下文,就是保存 CPU 执行时的一些数据
3)进程调度信息
在OS 进行调度时,必须了解进程的状态及有关进程调度的信息。这些信息包括:
- 进程状态:指明进程的当前状态,作为进程调度和对换时的依据。
- 进程优先级:用于描述进程使用处理机的优先级别的一个整数,优先级高的进程应优先获得处理机。
- 进程调度所需的其它信息:它们与所采用的进程调度算法有关,比如,进程已等待 CPU 的时间总和、进程已执行的时间总和等
- 事件:指进程由执行状态转变为阻塞状态所等待发生的事件,即阻塞原因。
4)进程控制信息
指用于进程控制所必须的信息,它包括:
- 程序和数据的地址:进程实体中的程序和数据的内存或外存地址,以便再调度到该进程执行时,能从 PCB 中找到其程序和数据。
- 进程同步和通信机制:这是实现进程同步和进程通信时必需的机制,如消息队列指针、信号量等,它们可能全部或部分地放在 PCB 中。
- 资源清单:在该清单中列出了进程在运行期间所需的全部资源另外还有一张已分配到该进程的资源的清单。
- 链接指针:给出了本进程(PCB)所在队列中的下一个进程的 PCB 的首地址。
(3)PCB 的组织方式
在一个系统中,通常可拥有数十个、数百个乃至数千个 PCB。为了能对它们加以有效的管理,需要用适当的方式将这些 PCB 组织起来。常用的组织方式有以下三种:
1)线性方式
该方式将系统中所有的 PCB 都组织在一张线性表中,将该表的首址存放在内存的一个专用区域中。该方式实现简单、开销小,但每次查找时都需要扫描整张表,因此适合进程数目不多的系统。// 一个数组
下图为线性表的 PCB 组织方式:
2)链接方式
该方式把具有相同状态进程的 PCB 分别通过 PCB 中的链接字链接成一个队列。这样,可以形成就绪队列、若千个阻塞队列和空白队列等。// 多个队列
下图为链式队列的组织方式图示:
3)索引方式
该方式根据所有进程状态的不同,建立几张索引表,例如,就绪索引表、阻塞索引表等,并把各索引表在内存的首地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个 PCB 在 PCB 表中的地址。// 还是队列,只是队列中存的是索引,中间加了索引表
下图为索引方式的 PCB 组织图示:
3、进程的控制
进程控制是进程管理中最基本的功能,主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换等功能。进程控制一般由 OS 内核中的原语来实现。// 所谓原语就是原子性质的程序语句,不能被中断和分开执行
// 进程控制也就是把 PCB 从一个特定队列调到另一个特定队列的操作过程
(1)操作系统内核
现代操作系统一般将 OS 划分为若干层次,再将 OS 的不同功能分别设置在不同的层次中。
通常将一些与硬件紧密相关的模块(如中断处理程序等)、各种常用设备的驱动程序以及运行频率较高的模块(如时钟管理、进程调度和许多模块所公用的一些基本操作),都安排在紧靠硬件的软件层次中,将它们常驻内存,即通常被称为的 OS 内核。// 仅靠硬件的软件层次
这种安排方式的目的在于两方面:
- 一是便于对这些软件进行保护,防止遭受其他应用程序的破坏。
- 二是可以提高 OS 的运行效率。
相对应的是,为了防止OS 本身及关键数据(如 PCB等)遭受到应用程序有意或无意的破坏,通常也将 CPU 的执行状态分成系统态和用户态两种。
- 系统态:具有较高的特权,能执行一切指令,访问所有寄存器和存储区,传统的 OS都在系统态运行。
- 用户态:具有较低特权的执行状态,仅能执行规定的指令,访问指定的寄存器和存储区。一般情况下,应用程序只能在用户态运行,不能去执行OS指令及访问OS区域,这样可以防止应用程序对OS的破坏。
OS内核的两大功能:
- 支撑功能:该功能是提供给 OS 其它众多模块所需要的一些基本功能,以便支撑这些模块工作。其中三种最基本的支撑功能是:中断处理、时钟管理(时间片轮转)和原语操作。
- 资源管理功能:该功能包括进程管理、存储器管理、设备管理等。
什么是原语?
所谓原语(Primitive),就是由若干条指令组成的,用于完成一定功能的一个过程。它与一般过程的区别在于:它们是“原子操作(Action Operation)”。所谓原子操作是指,一个操作中的所有动作要么全做,要么全不做。换言之,它是一个不可分割的基本单位。因此,原语在执行过程中不允许被中断。原子操作在系统态下执行,常驻内存。在内核中可能有许多原语,如用于对链表进行操作的原语、用于实现进程同步的原语等。
(2)进程的创建
1)进程的层次结构
在OS中,允许一个进程创建另一个进程,通常把创建进程的进程称为父进程,而把被创建的进程称为子进程。子进程可继续创建更多的孙进程,由此便形成了一个进程的层次结构。// UNIX
进程间的这种层次结构关系使得子进程可以继承父进程所拥有的资源,例如,继承父进程打开的文件,继承父进程所分配到的缓冲区等。当子进程被撤消时,应将其从父进程那里获得的资源归还给父进程。此外,在撤消父进程时,也必须同时撤消其所有的子进程。为了标识进程之间的家族关系,在 PCB 中设置了家族关系表项,以标明自己的父进程及所有的子进程。进程不能拒绝其子进程的继承权。
// 注意:在Windows 中不存在任何进程层次结构的概念,所有的进程都具有相同的地位。不同系统不一样
2)引起创建进程的事件
导致一个进程去创建另一个进程的典型事件有四类:
- 用户登录:在分时系统中,用户在终端键入登录命令后,若登录成功,系统将为该用户建立一个进程,并把它插入就绪队列中。
- 作业调度:在多道批处理系统中,当作业调度程序按一定的算法调度到某个作业时,便将它装入内存,为它创建进程,并把它插入就绪队列中。
- 提供服务:当运行中的用户程序提出某种请求后,系统将专门创建一个进程来提供用户所需要的服务。
- 应用请求:上述三种情况都是由系统内核为用户创建一个新进程,而应用请求事件则是由用户进程自己创建新进程,从而能够以并发运行的方式完成特定任务。
3)进程的创建步骤
每当出现了创建新进程的请求后,OS 便调用进程创建原语 Creat 按下述步骤创建一个新进程:
- 申请空白 PCB:为新进程申请获得唯一的数字标识符,并从 PCB 集合中索取一个空白 PCB。
- 为新进程分配其运行所需的资源:包括各种物理和逻辑资源,如内存、文件、I/O 设备和 CPU 时间等。
- 初始化进程控制块(PCB)。
- 如果进程就绪队列能够接纳新进程,便将新进程插入就绪队列。
(3)进程的终止
1)引起进程终止(Termination of Process)的事件
- 正常结束,表示进程的任务已经完成,准备退出运行。
- 异常结束,是指进程在运行时发生了某种异常事件,使程序无法继续运行。
- 外界干预,是指进程应外界的请求而终止运行。
2)进程的终止过程
如果系统中发生了要求终止进程的某事件,OS 便调用进程终止原语,按下述过程去终止指定的进程:
- 根据被终止进程的标识符,从 PCB 集合中检索出该进程的 PCB,从中读出该进程的状态。
- 若被终止进程正处于执行状态,应立即终止该进程的执行,并置调度标志为真,用于指示该进程被终止后应重新进行调度。
- 若该进程还有子孙进程,还应将其所有子孙进程也都予以终止,以防它们成为不可控的进程。
- 将被终止进程所拥有的全部资源或者归还给其父进程,或者归还给系统。 // 归还 PCB 的过程
- 将被终止进程(PCB)从所在队列中移出,等待其它程序来搜集信息。
(4)进程的阻塞与唤醒
1)引起进程阻塞和唤醒的事件
有下述几类事件会引起进程阻塞或被唤醒:
- 向系统请求共享资源失败。由于系统无足够的资源分配,进程不能继续运行而转变为阻塞状态。当其它进程释放出打印机时,请求进程才被唤醒。
- 等待某种操作的完成。当进程启动某种操作后,如果该进程必须在该操作完成之后才能继续执行,则应先将该进程阻塞起来,以等待操作完成。// 如等待 I/O 操作
- 新数据尚未到达。对于相互合作的进程,如果一个进程需要先获得另一进程提供的数据后才能对该数据进行处理,只要其所需数据尚未到达,进程便只有阻塞。
- 等待新任务的到达。例如,在网络环境中的发送进程,其主要任务是发送数据包,若已有的数据包已全部发送完成,而又无新的数据包发送,这时发送进程将把自己阻塞起来,仅当有新的数据包到达时,才将发送进程唤醒。
2)进程的阻塞过程
正在执行的进程,如果发生了阻塞事件,进程便通过调用阻塞原语 block 将自己阻塞。阻塞是进程自身的一种主动行为。
进入 block 过程后,由于该进程还处于执行状态,所以应先立即停止执行,把进程控制块中的状态由“执行”改为阻塞,并将 PCB插入阻塞队列。如果系统中设置了因不同事件而阻塞的多个阻塞队列,则应将本进程插入到具有相同事件的阻塞队列。// 将PCB插入阻塞队列
最后,转调度程序进行重新调度,将 CPU 分配给另一就绪进程,并进行切换,同事,保留被阻塞进程的 CPU 状态,按新进程的 PCB 中的 CPU 状态设置 CPU 的环境。// 释放CPU,保存CPU 状态
3)进程的唤醒过程
当被阻塞进程所期待的事件发生时,比如它所启动的 I/O 操作已完成,或其所期待的数据已经到达,则由有关进程(比如提供数据的进程)调用唤醒原语 wakeup,将等待该事件的进程唤醒。
wakeup 执行的过程是:首先把被阻塞的进程从等待该事件的阻塞队列中移出,将其 PCB 中的现行状态由阻塞改为就绪,然后再将该 PCB 插入到就绪队列中。// 从阻塞队列移入就绪队列
block 原语和 wakeup 原语是一对作用刚好相反的原语,必须成对使用,即如果在某进程中调用了阻塞原语,则必须在与之相合作的、或其它相关的进程中安排一条相应的唤醒原语,以便能唤醒被阻塞进程。否则,阻塞进程将会因不能被唤醒而永久地处于阻塞状态,再无机会继续运行。// 阻塞原语和唤醒原语必须成对使用
(5)进程的挂起与激活
1)进程的挂起
当系统中出现了引起进程挂起的事件时,OS 将利用挂起原语 suspend 将指定进程或处于阻塞状态的进程挂起。suspend 的执行过程是:
- 首先检查被挂起进程的状态,若处于活动就绪状态,便将其改为静止就绪,对于活动阻塞状态的进程,则将之改为静止阻塞。
- 为了方便用户或父进程考查该进程的运行情况,而把该进程的 PCB 复制到某指定的内存区域。
- 最后,若被挂起的进程正在执行,则转向调度程序重新调度。
2)进程的激活过程
当系统中发生激活进程的事件时,OS 将利用激活原语 active,将指定进程激活。
激活原语先将进程从外存调入内存,检查该进程的现行状态,若是静止就绪,便将之改为活动就绪。若为静止阻塞,便将之改为活动阻塞。
假如采用的是抢占调度策略,则每当有静止就绪进程被激活而插入就绪队列时,便应检查是否要进行重新调度,即由调度程序将被激活的进程与当前进程两者的优先级进行比较,如果被激活进程的优先级低,就不必重新调度,否则,立即剥夺当前进程的运行,把 CPU 分配给刚刚被激活的进程。// 根据进程优先级分配就绪进程的 CPU 使用权