题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
  • 在告示牌上显示某一时刻各方向来车的数量 clc2
  • 要修改告示牌上的车辆数量必须互斥进行, 为此设置信号量 x1x2
  • 若某方向的车辆需要通过时, 则首先要将该方向来车数量 c1c2 增加 1
  • 并查看自己是否是第一个进入单行线的车辆
    • 若是, 则获取单行线的信号量 y
    • 并进入单行线
  • 通过此路段以后出单行线时, 将该方向的车辆数 clc2 减 1
    • 当然是用 x1x2 来互斥修改
    • 并查看自己是否是最后一辆车
      • 若是, 则释放单行线的互斥量 y
      • 否则保留信号量 y
      • 让后继车辆继续通过
  • 双方的操作如出一辙
  • 考虑出现一个极端情况, 即当某方向的车辆首先占据单行线并后来者络绎不绝时
    • 另一个方向的车辆就再没有机会通过该单行线了
  • 这种现象是由于算法本身的缺陷造成的
    • 不属于因为特殊序列造成的饥饿
    • 所以它是真正的饥饿现象
  • 由于有信号量的控制, 因此死锁的可能性没有了
    • 双方同时进入单行线
    • 在中间相遇
    • 造成双方均无法通过的情景
  • 假设 P1 进程稍快, P2 进程稍慢, 同时运行
  • P1 进程首先进入 if 条件语句, 因此获得了 y 的互斥访问权
    • P2 被阻塞
  • 在第一个 P1 进程未释放 y 之前, 又有另一个 P1 进入
    • cl 的值变成 2
  • 当第一个 P1 离开时, P2 仍然被阻塞
    • 这种情形不断发生
  • 在这种情况下会发生什么事?
    • P1 顺利执行
    • P2 很郁闷, 长期被阻塞
  • 综上所述, 不会发生死锁, 但会出现饥饿现象
  • 因此选 B