操作系统
进程R
进程W1
进程W2
图6-14 W、R1、R2的相互制约关系
这里有3个问题需要解释。
(1)在进程R中,把数存入B之后,应该根据数的奇、偶性,来决定是向进程W1发消息,还是向进程W2发消息。这样,才能给予W1或W2从B里取数的机会。
(2)由于在进程R里已经对数的奇、偶性做了判断,所以进程W1或W2到缓冲区B里取数时,不必对它再行判断,取出的内容肯定是所需要的,不会弄错。
(3)假定在进程R没有执行之前,进程W1和W2都先于它执行了。那么这时由于信号量SO和SE的值都是0,所以它们都无法执行下去,分别在SO和SE的有关队列上等待。当进程R被调度到、判定放入B的数是奇数还是偶数,并向W1或W2发消息后,它们两个中的一个才会被唤醒,才会到B里去取数。
还可以从别的角度出发,去理解本题目中R、W1、W2之间的制约关系,从而得到它的另一种解决办法。图6-15给出了流程图,只需设置两个信号量:
S——初值为1;
G——初值为0。
这里有3个问题需要解释。
(1)信号量S用于资源分配。进程R通过P(S)申请使用缓冲区B。申请到后,才向里面存放数,然后就在信号量G上执行一个V操作,笼统地告诉进程W1或W2:缓冲区B里有数可取了。由于并不知道这个数的奇、偶性,所以,它们两个谁去取都是可以的。 (2)这时判断缓冲区B里数的奇、偶性,是在进程W1或W2里进行的。运行W1时,如果判定B里的是奇数,那么进程W1就可以将其取出,然后释放缓冲区B(通过V(S)实现)。如果判定B里的是偶数,那么进程W2就可以将其取出,然后释放缓冲区B(通过V(S)实现)。
操作系统
进程R
进程W1 进程W2
图6-15 W、R1、R2的另一种相互制约关系
(3)要注意的是,如果在进程W1里判定B中的数不是奇数,那么它就不应该取出此数。同样地,如果在进程W2里判定B中的数不是偶数,那么它就不应该取出此数。既然它没有取,表明数还在缓冲区B里。所以要通过V(G),使信号量G恢复原来的取值(含义是告诉要去取数的进程:B里有数要取),以便给另一个进程去取的机会。如果不做这一步,那么信号量G的当前值是0,无论进程W1还是W2在它的上面再执行P(G)时,就都无法通过,两个进程就会全被阻塞,进入死锁。所以,进程W1和W2里的V(G)是非常重要的。 5.在飞机订票系统中,假定公共数据区的单元Ai(i=1,2,3…)里存放着某月某日第i次航班现有票数。在第j个售票处,利用变量Rj暂存Ai里的内容。现在为第j个售票处编写代码如图6-16(即教材中的图6-30)所示。试问它的安排对吗?如果正确,试说明理由;如果不对,指出错误,并做出修改。
解:从图6-16可以知道,公共数据区的单元Ai(i=1,2,3…)里存放的某月某日第i次航班的现有票数,是j(j=1,2,3…)个售票处共享的数据。因此,这些售票处对公共数据区的单元Ai(i=1,2,3…)的操作不能同时进行。正因为如此,图中把对Ai的这些操作,用名为S的信号量上的P、V操作,保证它们互斥进行。这样处理都是正确的。
售第j售票处要订
第i航班的飞机票
按旅客要求找到Ai
(进入公共数据监界区)
Rj=Ai;
(取出该航班现有票数)
(还有这Rj(售完!”
(退出
图6-16 第j售票处的售票程序
操作系统
关键是当判定没有第i次航班的机票时,图6-28里仅安排了打印“票已售完!”的动作。这样,第j售票处只有进入临界区的P(S),而没有执行
退出临界区的V(S)。它没有退出临界区,别的售票窗口也就无法再进入这个临界区。所以,这种安排是不对的。应该把图6-16改成为图6-17,这样就完全正确了。
第j售票处要订 第i航班的飞机票
按旅客要求找到
Ai
(进入公共数据监界区)
Rj=Ai;
(取出该航班现有票数)
(还有这Rj(进完!”
界区)
(退出售
图6-17 正确的第j售票处的售票程序