题23
题目
Q:下面是并发进程的程序代码, 正确的是 ( )。
Semaphore x1=x2=y=1;
int cl=c2=0;
P1()
{
while(1){
P(x1);
if(++c1==1)P(y);
V(x1);
computer (A);
P(x1);
if(--c1==0)V(y);
V(x1);
}
}
P2()
{
while(1){
P(x2);
if(++c2==1)P(y);
V(x2);
computer (B);
P(x2);
if(--c2==0)V(y);
V(x2);
}
}A. 进程不会死锁, 也不会 “饥饿”
C. 进程会死锁, 但是不会 “饥饿”
B. 进程不会死锁, 但是会 “饥饿”
D. 进程会死锁, 也会 “饥饿”
分析
A:这里的P()是wait()的意思, V()是signal()的意思, 也就是说, P(x1)是对信号量x1进行等待操作, V(x1)是对信号量x1进行释放操作
解
B
- 这是一个扩展的单行线问题
- 单行线只允许单方向的车辆通过
- 在单行线的入口设置信号量
y - 在告示牌上显示某一时刻各方向来车的数量
cl和c2 - 要修改告示牌上的车辆数量必须互斥进行, 为此设置信号量
x1和x2 - 若某方向的车辆需要通过时, 则首先要将该方向来车数量
c1或c2增加 1 - 并查看自己是否是第一个进入单行线的车辆
- 若是, 则获取单行线的信号量
y - 并进入单行线
- 若是, 则获取单行线的信号量
- 通过此路段以后出单行线时, 将该方向的车辆数
cl或c2减 1- 当然是用
x1或x2来互斥修改 - 并查看自己是否是最后一辆车
- 若是, 则释放单行线的互斥量
y - 否则保留信号量
y - 让后继车辆继续通过
- 若是, 则释放单行线的互斥量
- 当然是用
- 双方的操作如出一辙
- 考虑出现一个极端情况, 即当某方向的车辆首先占据单行线并后来者络绎不绝时
- 另一个方向的车辆就再没有机会通过该单行线了
- 这种现象是由于算法本身的缺陷造成的
- 不属于因为特殊序列造成的饥饿
- 所以它是真正的饥饿现象
- 由于有信号量的控制, 因此死锁的可能性没有了
- 双方同时进入单行线
- 在中间相遇
- 造成双方均无法通过的情景
- 假设
P1进程稍快,P2进程稍慢, 同时运行 P1进程首先进入if条件语句, 因此获得了y的互斥访问权P2被阻塞
- 在第一个
P1进程未释放y之前, 又有另一个P1进入cl的值变成 2
- 当第一个
P1离开时,P2仍然被阻塞- 这种情形不断发生
- 在这种情况下会发生什么事?
P1顺利执行P2很郁闷, 长期被阻塞
- 综上所述, 不会发生死锁, 但会出现饥饿现象
- 因此选 B