4.3 进程控制

4.3.1 进程控制的概念

进程控制的职责是对系统中的全部进程实施有效的管理,它是处理机管理功能一部分,当系统允许多进程并发执行时,为了实现共享、协调并发进程的关系,处理机管理就必须提供对进程实行有效控制的功能。操作系统的核心具有创建、撤消进程和实施进程间同步、通信等功能。这些功能是由一些具有特定功能的程序段组成的,而且是通过执行各种原语操作来实现各种控制和管理功能的。原语是一种特殊的系统调用命令,它可以完成一个特定的功能,一般为外层软件所调用,其特点是原语执行时不可中断,所以原语操作具有原子性,它是不可再分的。在操作系统中原语作为一个基本单位出现。

用于进程控制的原语有:创建原语、撤消原语、阻塞原语、唤醒原语等。

对于用户来说,在多进程环境中,它具有一个主进程和可能出现的同时活动的附属进程。为了完成用户程序的任务,用户必须控制这些进程的活动。操作系统应能提供控制功能,用户则通过服务请求方式获得这些功能。

4.3.2 进程创建

进程管理的基本功能之一是创建各种新的进程,这些新进程是一个与现有进程不同的实体。在系统生成时,要创建一些必需的、承担系统资源分配和管理工作的系统进程。对于用户作业,每当调作业进入系统时,由操作系统的作业调度进程为它创建相应的进程。在层次结构的系统中,允许一个进程创建一些附属进程,以完成一些可以并行的工作。创建者称为父进程,被创建者称为子进程,创建父进程的进程笔名为祖父进程,这样就构成了一个进程家族。但用户为能直接创建进程,右办能通过系统请求方式向操作系统申请创建进程。

无论是系统或是用记创建时程都必须调用创建原语来实现。创建原语的主要功能是创建一个指定标识符的进程。主要任务是形成该进程的进程控制 pcb 。所以,调用者必须提供形成 pcb 的有关参数,以便在创建时填入。这些参数是:进程标识符、进程优先级、本进程开始地址等。其他资源从父进程那里继承。如在 UNIX 系统中,父进程创建一个子进程时,该子进程继承父进程占用的系统资源,以及除进程标识符外的其他特性,较详细的介绍见第十章。

创建原语的形式为

create(name,priority,start-addr)

其中, name 为被创建进程的标识符, priority 为进程优先级, start-addr 为某程序的开始地址。创建原语的实现过程见 MODULE4.5 。在程序中,“从 pcb 资源池申请一个空闲的 pcb 结构”这一条语句要稍加说明。 pcb 资源池就是 pcb 集合,如图 4.10 所示。它是在系统存储区开辟的一片区域,用来存放所有的进程控制块。创建原语的形式化描述见 MODULE4.5 。

MODULE4.5 进程创建

算法 create

输入:新进程的符号名,优先级,开始执行地址

输出:新创建进程的内部标识符 pid

{

在总锭队列上查找有无同名的进程;

if (有同名进程)

return (错误码); /* 带错误码返回 */

 

从 pcb 资源池申请一个空闲的 pcb 结构;

If (无空 pcb 结构)

return (错误码) /* 带错误码返回 */

用入口参数设置 pcb 内容;

置进程为“就绪”态;

将新进程的 pcb 入就绪队列;

新新进程的 pcb 入总链队列;

retrun (新进程的 pid )

}

 

该集合的大小为 n × (pcb-size) 。其中, pcb-size 为 pcb 结构的大小, n 为系统具有的 pcb 个数。该 pcb-size 的始址和 n 值由系统生成时确定。系统初始时,每个 pcb 结构中进程标识符单元内都存入“ -1 ”,表示该 pcb 结构为空。当创建原语执行成功后,该项内容为新创建时程的标识符。

4.3.3 进程撤消

一个进程由进程创原语创建,当它完成了其任务之后就希望终止自己。这时,应使用时程撤消原语,其命令形式为 kill( 或 exit) 。该命令没有参数,其执行结果也无返回信徙。它的功能是将当前运行进程(因为是自我撤消)的 pcb 结构归还到 pcb 资源池,所占用的资源归还给父进程,从总链队列中摘除它,然后转进程调度程序。因为调用者自己已被撤消,所以应由进程调度再选一个进程去运行。进程撤消原语算法描述见 MODULE4.6 。

MODULE4.6 进程撤消

算法 kill

输入:无

输出:无

{

由运行指针得当前进程的 pid ;

释放本进程所占用的资源给父进程;

该进程从总链队列中摘除;

释放此 pcb 结构

转进程调度程序

}

 

4.3.4 进程等待

有了创建原语和撤消原语,虽在进程可以从无到有、从存在到消亡而变化,但还不能完成进程各种状态的过渡。例如,由“运行过渡到“等待”,由“等待”转变为“就绪”,需要通过进程之间的同步或通信机构来实现,但也可直接使用等待原语和唤醒原语来实现。下面先讨论等待原语(或称挂起命令)。

当进程需要等待某一事件完成时,它可以调用等待原语把自己挂起。而一旦被挂起,它只能由另一个进程唤醒。进程等待命令形式为

susp(chan)

入口参数 chan :进程等待的原因

等待命令的功能是:停止调用进程的执行,将 CPU 现场保留到该进程的 pcb 现场保护区;然后,改变其状态为“等待”,并加入到等待 chan 的等待队列;最后使控制转向进程调度,以选择下一个进程。进程等待(挂起)原语的描述见 MODULE4.7 。

MODULE4.7 进程等待(挂起)

算法 susp

输入: chan 等待的事件(等待)

输出:无

{

保护现行进程的 CPU 现场到 pcb 结构中;

置该进程为“等待”态;

将该进程 pcb 插入到等 chan 的等待队列;

转进程调度;

}

 

4.3.5 进程唤醒

进程由“运行”转变为“等待”状态是由于进程必须等待某一事件的发生,所以处于等待状态的进程是绝对不可能叫醒自己的。比如,若某进程正在等待 I/O 操作完成或等待别的进程发消息给它,则只有当该进程所期待的事件出现时,才由发现者进程用唤醒原语叫醒它。一般说来,发现者进程和被唤醒进程是合作的并发进程。唤醒原语的命令形式为

wakeup(chan)

唤醒原语的功能是:当进程等待的事件发生是时,唤醒等待该事件的所有进程。进程唤醒原语的算法描述见 MODULE4.8 。

MODULE.8 进程唤醒

算法 wakeup

输入: chan 等待的事件(等待原因)

输出:无

{

保护现行进程的 CPU 现场到 pcb 结构中;

置该进程为“就绪”态;

将该进程进入就绪队列;

找到该等待原因的队列指针;

For (该队列上每一个等待的进程)

{

将进程移出此等待队列;

置进程状态为“就绪”;

将进程入就绪队列;

}

转进程调度;

}

 

唤醒原语的最后一步可以转进程调度,也可返回现行进程。这要由系统设计者决定。接常理,当发现者进程唤醒了一个等待某事件的进程后,控制仍应返回现行程序。但有的系统,为了造成更多的调度机会,一般在实施进程控制功能后转进程调度,以便让调度程序有机会去选择一个合适的进程来运行。

4.3.6 进程延迟

(一)通用延迟过程

当某进程需要延迟一段时间再执行时,它发出 delay 命令,由操作系统的延迟过程完成此功能。进程延迟过程的算法描述见 MODULE4.9 。其功能是:将需要延迟的进程的 pcb 结构按其延迟时间加紧入到延迟队列中的适当位置上。首行保护调用者的 CPU 现场,再计算请求延迟的进程所需延迟的时间,这一时间是进程所需要延迟的少数乘以时钟速率而得到的,即 clock-ticks(clock-ticks=secs × (clock-rate)), 然后以 clock-ticks 数值为依据检索延迟队列,把这个延迟进程插入到延迟队列的合适位置中。

MODULE4.9 进程延迟

算法 delay

输入: seconds /* 需延迟的秒数 */

输出:无

{

保护调用进程的 CPU 现场;

Clod-ticks=seconds × (clock-rate) ; /* 需延迟的机内时间 */

封锁延迟队列;

以 clock-ticks 值查寻延迟队列;

找到合适位置插入; /* 延迟队列按需延迟时间的上升顺序排序 */

解锁延迟队列;

置该进程为延迟状态;

转进程调度;

}

延迟队列结构如图 4.11 所示。为了实现延迟功能,在 pcb 中增加了一个 deltatime 项,其内容为进程所需延迟的 clock-ticks 总数与延迟队列中前一个进程的 clock-ticks 总数之差。假定进程 A 、进程 B 和进程 C 所需延迟的 clock-ticks 总数分别为 2 , 5 和 10 ,则在 pcb a 、 pcb b 和 pcb c 的 deltatime 这一项中的内容分别为 2 , 3 和 3 ,即延迟队列按延迟时间上各顺序排列。

假定有一个进程需延迟的 clock-ticks=8 ,它应插入图 4.12 所示的队列的什么位置呢?首先应将 clock-ticks 值送入要延迟进程 pcb 的 deltatime 项中(记为 deltatime mew ),然后以此值与延迟队列中的每一个进程的 deltatime (记为 deltatime pcb i )相关减得 time ,即 time=deltatime nwe -deltatime pcb i 。若此差值为正,则以这个差值作为要延迟进程的 deltatime 项的新值,继续比较。当差值为负值时,表示已找到了合适的位置,应将要延迟进程的 pcb 插入到相比较的这个进程的前面,而后者的 deltatime 值应为二者相减的差值(取正值),至此,这一工作就完成了。图 4.12 说明了这一查找过程。

 

(b)pcb new 与 pcb a 比较后

(b)pcb new 与 pcb b 比较后

 


图 4.12 一个延迟进程插入延迟队列中

 

(二)延迟唤醒进程

当某一进程延迟时间到时,由延迟唤醒进程把它唤醒。延迟唤醒进程是一个系统进程,它在系统初始化时被创建,之后它连续地执行直到系统关闭。该时程是由时钟中断激活的,当时钟中断来到时,它取延迟队列首元素,将其 deltatime 值减 1 ,并判断是否为零。若为零,则将该进程移入就绪队列,然后中断返回,等下一次时钟中断的到来。若不为零,则该进程也返回,再等待下一次时钟中断的到来。

不论是延迟唤醒进程还是通用延迟过程都要使用延迟队列。为了保证队列的完整性,在进行队列操作时必须封锁延迟队列,操作完毕后再解锁。
 
 Copyright © 2007 华中师范大学计算机科学系  All Rights Reserved