信号量PV操作时,P操作的sem修改与sem条件判断的顺序不能互换
匿名2023/07/31 19:49:40提问
    2018lecture18student
329

PPT上的PV操作:

classSemaphore {
    int sem;
    WaitQueue q;
}

Semaphore::P() { sem--; if (sem < 0) { Add this thread t to q; block(p); } }

Semaphore::V() { sem++; if (sem<=0) { Remove a thread t from q; wakeup(t); } }

在课堂上,陈渝老师提到,能否将程序修改为如下情形(sem初始化是1):

P(){ 
if (sem <= 0) {
q. enqueue(t);
block(t);
}
sem--;
}

V() {
sem++;
if (!q.empty()) {
t = q.dequeue();
wakeup(t);
}
}

比如,一个例子:

(以下以Pn表示进程n执行P操作,Vn表示进程n执行V操作)

P1,sem=0,q=[],1进入临界区

P2,sem=0,q=[2],2被阻塞,不能执行sem--

V1,sem=1,q=[],2被唤醒,接着2执行sem--,sem=0,并且2进入临界区。

看似是没有问题的,但其实:

P1,sem=0,q=[],1进入临界区

P2,sem=0,q=[2],2被阻塞,不能执行sem--

V1,sem=1,q=[],2被唤醒,此时2处于就绪态,当进程调度时,如果没有马上调度2,比如调度了3,执行P3,3发现sem=1,于是直接跳到sem--并且进入临界区;而3在临界区的过程中,若发生进程切换,切到2时,2执行sem--,sem=-1,并且2也进入临界区。这就导致会有多个进程进入临界区的情况。因此这种做法是不可取的。

回答(1
    推荐问答
      Simple Empty
      暂无数据