题干
类读者写者问题
有P1、P2、P3三类进程共享同一表格F,其中P1对F只读不写,P2对F只写不读,P3对F先读后写。不同进程可同时读F,但如果有进程写时,其余进程不能读或写。请用信号量以及P、V操作给出解决方案,并做一定分析。
理发师问题
理发店中有一位理发师,一把理发椅,N个候坐用的凳子。若无顾客,则理发师睡觉,且第一个顾客到来时叫醒理发师;若理发师正理发时有顾客到店,有空凳子就坐下,没有就离开。请用信号量以及P、V操作给出解决方案。
解法
类读者写者问题
简要分析:这是典型的读者写者问题,P1相当于读者,P2为写者,P3则是先读者后写者的角色。(本解答只是其中两种较简单的解法)
作答:
解法一
// 设置信号量以及相关参数
semaphore w = 1; //用以保持读者写者、写者写者互斥
semaphore mutex = 1; //用以互斥访问count
int count = 0; //用以记录当前读者数
P1(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
count--;
if (count == 0) V(w);
V(mutex);
}
}
P2(){
while(1) {
P(w);
writing...
V(w);
}
}
P3(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
count--;
if (count == 0) V(w);
V(mutex);
P(w);
writing...
V(w);
}
}
简要分析:此解法满足读者优先的策略,因为一旦有读者进程进入便可抢占插入到写者进程之前。
解法二
// 设置信号量以及相关参数
semaphore rw = 1; //用以保持读者写者、写者写者互斥
semaphore w = 1; //用以实现读写公平
semaphore mutex = 1; //用以互斥访问count
int count = 0; //用以记录当前读者数
P1(){
while(1) {
P(w);
P(mutex);
if (count == 0) P(rw);
count++;
V(mutex);
V(w);
reading...
P(mutex);
count--;
if (count == 0) V(rw);
V(mutex);
}
}
P2(){
while(1) {
P(w);
P(rw);
writing...
V(rw);
V(w);
}
}
P3(){
while(1) {
P(mutex);
if (count == 0) P(w);
count++;
V(mutex);
reading...
P(mutex);
if (count == 0) V(w);
count--;
V(mutex);
P(w);
P(rw);
writing...
V(rw);
V(w);
}
}
简要分析:此解法可实现较为公平的读写,因为此解法遵循先来先服务的原则。
理发师问题
对于理发师问题,可设置三个信号量加以解决
semaphore mutex = 1; //用于互斥访问count
semaphore barber = 0; //可理解为可用的理发师资源(清醒时)
semaphore customer = 0; //可理解为等待理发的顾客
int count = 0; //相当于customer的计数
Barber(){
while(1) {
P(customer); //等候顾客,即睡觉
P(mutex); //有顾客,进入临界区
count--;
V(barber); //可理解为释放一个理发师资源
V(mutex); //退出临界区
理发……
}
}
Customer(){
P(mutex); //有顾客来,进入临界区
if (count < N) { //若有空位置则坐下
count++; //等待顾客数加一
V(customer); //唤醒理发师
V(mutex); //退出临界区
P(barber); //可理解为申请一个理发师资源
理发……
} else { //没位置顾客离开理发店,退出临界区
V(mutex);
}
}