进行P0和P1的共享变量定义及其初值为
boolean flag[2];
int turn=0;
flag[0]=faulse; flag[1]=faulse;
若进行P0和P1访问临界资源的类C代码实现如下:
Void P0( )//进程p0 Voicl P1( )//进程p1
while(TuRE) while(TURE)
Flag[0]=TURE;Flag[1]=TuRE;
turn=1; turn=0;
While(flag[1]&&(turn==1)) While(flag[0]%&(turn==0))
; ;
临界区; 临界区;
Flag[0]=FALSE; Flag[1]=FALSE;
则并发执行进程P0和P1时产生的情况是:
A.不能保证进程互斥进入临界区,会出现“饥饿”现象
B.不能保证进程互斥进入临界区,不会出现“饥饿”现象
C.能保证进程互斥进入临界区,会出现“饥饿”现象
D.能保证进程互斥进入临界区,不会出现“饥饿”现象
参考答案:D
解析: 考查进程间通信与Peterson算法。
算法实现互斥的主要思想在于设置了一个turn变量,用于进程间的互相谦让。
如果进程P0试图访问临界资源,flag[0]=true,表示希望访问。此时如果进程P1还未试图访问临界资源,则flag[1]在进程上一次访问完临界资源退出临界区后已设置为false。所以进程P0在执行循环判断条件时,第一个条件不满足,进程P0可以正常进入临界区,且满足互斥条件。
我们需要考虑的是两个进程同时试图访问临界资源的情况。
注意turn变量的含义:进程在试图访问时,首先设置自己的flag变量为true,表示希望访问;但又设置turn变量为对方的进程编号,表示谦让,因为在循环判断条件中turn变量不是自己编号时就循环等待。
这时两个进程就会互相“谦让”一番,但是这不会造成“饥饿”的局面,因为turn变量会有一个最终值,所以必定有进程可以结束循环进入临界区。实际的情况是,先作出“谦让”的进程先进入临界区,后作出“谦让”的进程则需要循环等待。其实这里可以想象为两个人进门,每个人进门前都会和对方客套一句“您走先”。如果进门时没别人,就当和空气说句废话,然后大步登门入室;如果两人同时进门,就互相请先,但各自只客套一次,所以先客套的人请完对方,就等着对方请自己,然后光明正大进门。