理发店理有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子。
如果没有顾客,理发师便在理发椅上睡觉一个顾客到来时,它必须叫醒理发师。
如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。
分析:
理发师进程分析:理发师开始工作时,先看一下店内有无顾客,如果没有,就打瞌睡(阻塞);如果有,就被唤醒,进行理发,且等待人数减1。由于理发师只要开始工作就有可能停不下来所以用while()循环。
顾客进程分析:每一位顾客一个进程,故有多个顾客进程。在每个进程中,如果顾客数超过座位数,就结束进程。否则等待理发师。顾客理完发(或无座位)就走,因此不需要while循环。
伪代码:
semaphore ba,cts,mutex;
ba=0,cts=0,mutex=1;
int waitng=0;
void barber()
{
P(cts); //请求顾客,没有顾客的话理发师睡觉
P(mutex); //顾客来了,进入临界区
waitng--; //等待的顾客数-1
V(ba); //理发师准备为顾客理发
V(mutex); //退出临界区
haircut(); //理发
}
void customer()
{
P(mutex); //进入临界区
if(waiting<n) //等待的人数小于椅子数量n
{
waiting++; //等待人数+1
V(cts); //唤醒理发师
V(mutex); //退出临界区
P(ba); //请求理发师理发
get_haircut(); //顾客完成理发
}
else V(mutex); //人满了,顾客直接离开
}
与之类似的还有操作员复印的问题:
复印室有一个操作员为顾客复印资料,有5把椅子供顾客休息并等待复印。如果没有顾客,则操作员休息。当顾客来到复印室时,如果有空椅子则坐下来。当操作员空闲时顾客站起来唤醒操作员进行复印,复印完后离开复印室;如果没有空椅子则离开复印室。试用P、V操作实现顾客和操作员活动的同步。
分析:
与理发师问题相同。
semaphore op,cts,mutex;
op=0,cts=0,mutex=1;
int waitng=0;
void operator()
{
P(cts); //请求顾客,没有顾客的话操作员睡觉
P(mutex); //顾客来了,进入临界区
waitng--; //等待的顾客数-1
V(op); //操作员准备复印
V(mutex); //退出临界区
print(); //进行复印
}
void customer()
{
P(mutex); //进入临界区
if(waiting<5) //等待的人数小于椅子数量
{
waiting++; //等待人数+1
V(cts); //唤醒操作员
V(mutex); //退出临界区
P(op); //请求操作员复印
get_print(); //顾客完成复印
}
else V(mutex); //人满了,顾客直接离开
}
。。。。