2.16.5 理发师睡觉问题
情境描述
- 理发店有一把理发椅子,五把等候椅子
- 无顾客时理发师睡觉,有则工作
- 顾客有空等候椅子则等候,否则离开
请用P、V操作来实现理发师睡觉问题
分析
- 同步过程:
- 理发师:有无顾客
- 顾客:有无理发椅子
- 客人:
- 判断有无空闲的等待椅子
- 等待顾客++
- 空闲椅子–
- 有无空闲理发椅子
- 空闲椅子++
- 唤醒理发师
- 理发
- 释放理发椅子
- 等待顾客–
- 顾客离开
伪代码
int n_customer= 0; //店里的顾客,含正在理发的人数
semaphore mutex = 1; //waiting的互斥信号量
semaphore bchair = 1; //理发椅的个数
semaphore wchair = 5; //空椅子的个数
semaphore ready = 0; //是否有顾客准备好
semaphore finish = 0; //理发师是否完成理发
main() {
cobegin baber(); customer(); coend }
void baber() //理发师进程
{
while (true) {
P(ready); //有顾客准备好了
理发;
V(finish); //允许其他顾客理发
}
}
void customer()
{
P(mutex); //互斥waiting变量的操作
if (n_customer < 6) //店里顾客数没达上限
{
n_customer ++; //店里顾客数增1
V(mutex); //允许waiting变量的操作
P(wchair); //找一个空椅子坐下
P(bchair); //再找理发椅坐下
V(wchair); //释放一个空椅子
V(ready); //该顾客准备好了
P(finish); //等待理发师完成理发
V(bchair); //离开理发椅
P(mutex); //互斥waiting变量的操作
n_customer --; //等待顾客数减1
V(mutex); //允许waiting变量的操作
}
else
离开;
V(mutex);
}
2.16.6 银行叫号问题
情景描述
某银行提供一个服务窗口和10个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。取号机每次仅允许一位顾客使用。当营业员空闲时,通过叫号选取一位顾客,并为其服务。顾客和营业员的活动过程描述如下:
cobegin{
process 顾客i{
从取号机上获取一个号码;等待叫号;获取服务;}
process 营业员{
while (true) {
叫号;为顾客服务;}}
}
请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。要求写出完成的过程,说明信号量的含义并赋初值。
伪代码
semaphore mutex = 1; //互斥使用取号机的信号量
semaphore empty = 10; //空座位的数量信号量
semaphore full = 0; //已占座位的数量信号量
semaphore service = 0; //等待叫号信号量
process 顾客i
{
P(empty);
P(mutex);
从取号机获得一个号;
V(mutex);
V(full);
P(service); //等待叫号
}
process 营业员
{
while (true) {
P(full);
V(empty);
V(service); //叫号
为顾客服务;
}
}
总结服务类问题:理发师、银行叫号
需要计算等待者的数量,并为这个统计量加锁