打瞌睡的理发师问题
有一个理发师,一把理发椅和 N 把供等候理发的顾客坐的椅子。
如果没有顾客,则理发师便在理发师椅子上睡觉;
当一个顾客到来时,必须唤醒理发师进行理发;
如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,他就坐下来等,如果没有空椅子,他就离开。
为理发师和顾客各编一段程序(伪代码)描述他们的行为,要求不能带有竞争条件。
这个问题和生产者消费者相似,顾客可以看做生产的产品,理发师可以看组是消费者,沙发有空位,顾客就坐进去,沙发有顾客,理发师就去理发。但是要主要,这个和生产者消费者最大的一个区别就是:
- 生产者生产出一个产品后,当缓存没有空位时,会一直等待下去,直到有空位出现
- 而此问题最关键的地方就是:如果没有空位,顾客直接离开,不会加入阻塞队列
int count = 0; //沙发上的顾客数,用来计数
semaphore customer = 0 ; //沙发上的顾客数,用来阻塞唤醒理发师
semaphore barber = 0; //表示正在理发的理发师数量
semaphpre mutex = 1;
//理发师
void barber{
while(true){
P(customer);//如果沙发有顾客,就起来理发,负责阻塞进不去,理发师打瞌睡
P(mutex);//进临界区,保护的是count,防止多个客户操作
count--;
V(mutex);
V(barber);
//理发。。。。
}
}
//顾客
//注意:如果没有空位了,顾客直接离开,不会进行阻塞,否则理完发离开,所以不需要while循环
void customer{
P(mutex);//进临界区
if(count < N)//沙发没满就坐进去理发,否则直接走
{
count++;
V(mutex);
V(customer);
P(barber);//如果理发师忙,则等待
}else{
V(mutex);
}
}