2.2.1 进程的引入

2.2.1 进程的引入

到目前为止,本书讨论计算机系统的运行程序时,有多种称呼,在批处理时称为作业,分时系统时称为用户程序或任务,大多数情况下又称为程序,这些称呼都关乎CPU的执行单元,那么到底应该如何称呼或描述所有这些CPU的活动呢?

其实在早期的计算机系统中一直采用程序这个概念,那时计算机系统只允许一次执行一个程序(单道程序),程序对系统有完全的控制权,能访问所有的系统资源。但是多道程序设计出现之后,多个程序可以同时在内存中存在,共享系统的所有资源,情况产生了变化,什么变化呢?下面就从单道程序与多道程序的不同说起。

单道环境下的程序特点统称为顺序可再现性,包括顺序性、封闭性和可再现性。

①顺序性:处理机的操作严格按照程序所规定的顺序执行,只有当一个操作结束后才能进行下一个操作。

②封闭性:程序是在封闭的环境下执行的,即程序运行的环境资源只能由程序本身访问和修改,与其他程序无关;环境资源包括程序本身使用的变量,更多的是程序运行时占用的系统资源,如程序地址栈、指令计数器等。

③可再现性:一个程序只要它的运行条件(初始数据)相同,不论运行速度如何,其运行结果一定相同,不管是运行错误或正确,并且每次运行过程都会不变地再现。

在多道环境下,程序可以并发执行,它们共享系统的所有资源,不再具有如上的程序的顺序可再现性,相对于顺序性、封闭性和可再现性,体现出的是与时间相关的不确定性,包括间断性、失去封闭性和不可再现性。

①间断性:对并发的程序的整体来说,它们相互制约,各程序在执行时间上是重叠的,即当一个程序还未执行完成,就开始了另一个程序的执行;对每一个程序来说,则出现“执行—暂停—执行”的间断特点。

②失去封闭性:并发的程序共享系统的某些资源,所以,一个程序的环境可能会受其他程序的影响,或说,一个程序可能会改变另一个程序的环境,程序环境不再封闭。

③不可再现性:以上的两个特点造成的后果就是,并发程序的运行过程和结果不确定,即使运行的初始条件(数据)相同,它在运行过程中会受到其他程序影响,而且这种影响不可预期,也无法再现,因此运行过程和结果不可再现。

多道环境下的间断性、失去封闭性和不可再现性统称为不确定性,也称为与时间相关的特性。为了更好地理解不确定性,下面举两个不确定性的例子。

【例2-1】两并发执行的程序P1、P2,共享公共变量N,程序如下:

两个程序并发执行,共享公共变量N,程序段P1不断累加变量N;程序段P2打印N后,将N清0。由于执行的顺序是不定的,所以两个程序并发执行的结果是不定的,也是不可再现的,充分体现了并发程序的间断性、失去封闭性和不可再现性。

运行结果:

7,0,0,100,0...?

2,4,5,0,0...?

?

【例2-2】多窗口并发火车售票。假设一个火车订票系统程序,其中读取某车次车票余额并售出车票的程序片段为ticket P,现在两个窗口T1和T2并发执行这段程序,两个并发程序必须共享某车次的剩余车票数的变量t Num,t Num是多个售票程序共享使用的环境。

程序如下:

同时售票的两个窗口T1和T2并发执行这段程序,若每段程序不加约束各自按自己的速度执行,每一时刻代表一个CPU单位,在一个时刻里只能有一个程序执行,将CPU分为6个时刻t0~t5,两个窗口运行的程序顺序可能有多种组合,出现多种执行序列,产生不同的执行结果。下面给出两种执行组合,一种产生正确的结果,一种产生不正确的结果,如图2-12所示。

图2-12 并发程序的结果不确定性示例

并发程序设定共享变量t Num的初值为1,即有一张火车票,按照图(a)的运行组合,系统中的这张车票由先执行的T1窗口卖出(t0~t2时刻),t3时刻窗口T2执行时,t Num为0,已经无票,程序返回,这个运行结果是正确的;图(b)显示的情况则不同了,尽管T1和T2正常执行,却把一张票卖给了两个窗口的两个旅客,这显然是错误的。分析原因是,窗口T1和T2运行的程序使用的变量是共享的,两个程序运行环境不封闭,T1中的变量t Num可以由T2的程序修改,T2中的变量t Num也可以由T1的程序修改,这样,T1读到有1张火车票,T2也读到有1张火车票,而T1将火车票卖出,修改了T2读到的变量值,而T2却不知,造成一票多售的情况。

这个例子充分表现了并发的程序有间断性〔在图(b)情况下,T1和T2都是执行—暂停—执行状态〕,失去封闭性和结果不可再现性〔T1和T2进程运行程序ticketP,不可预知是什么样的组合序列,如果形成图(a)组合,结果正确;如果形成图(b)组合,结果不正确〕正是与时间有关的错误。因此对一组并发程序的执行过程必须进行有效的控制,否则会造成不正确的结果。

由此也看出,程序这个概念已经无法体现多道环境下并发的特点,因此需要引进新的概念,这就是“进程”。