嗜睡的理发师问题

一、问题描述

一个理发店有N张沙发和一张理发椅。没有顾客要理发时,理发师便去睡觉。当一个顾客走进理发店时,如果所有的沙发都已被占用,他便离开理发店;否则,如果理发师正在为其他顾客理发,则该顾客就找一张空沙发坐下等待;如果理发师因无顾客正在睡觉,则由新到的顾客唤醒理发师为其理发。在理发完成后,顾客必须付费,直到理发师收费后才能离开理发店。试用信号量完成这一过程。

二、问题分析。

引入三个信号量:
① 信号量customs记录等候理发的顾客数,并起提醒理发师睡觉的作用,初始值为0;
② 信号量chairs记录剩下的沙发数,并起唤醒理发师作用,初始值为N;
③ 信号量mutex 用于互斥,初始值为1;
④ 定义常量CHAIRS=N.

三、代码:

//定义信号量 
int CHAIRS=N; //为顾客准备的椅子数
semaphore customers=0; //记录等候理发的顾客数,并用作阻塞理发师进程
semaphore chairs=n;//记录剩下空的椅子数,并用作唤醒理发师进程 
semaphore mutex=1;//用于互斥

//测试是否有空椅子,如果是第一个顾客唤醒理发师 
wait(chairs){
    chairs--;
    if(chairs==CHAIRS-1) wakeup_barber;
}
//理发师为一人理发,等待区少一人,释放椅子资源 
signal(chairs){
    chairs++;
}
//测试是否还有顾客,若无顾客理发师睡眠 
wait(customers){
    customers--;
    if(customers<0) barber_sleep; 
}
//顾客增加 
signal(customers){
    customers++;
}


void barber(){
	while(TRUE){ //是否还有顾客?
		wait(customers);wait(mutex); //若无顾客,理发师睡眠进程互斥
		get-haircut();pay-money(); //一个顾客理发收钱 
		signal(mutex); signal(chairs); //开放临界区释放椅子资源
    }
}

void customer(){
    wait(mutex); //进程互斥
    if(customers.value< CHAIRS){ //看看有没有空椅子
        wait(chairs); //必要的话唤醒理发师
        signal(mutex);signal(customers); //开放临界区多一人等待
    }else{
    	'signal(mutex); //人满了,顾客离开
	}
}

Void main(){
    cobegin   // 并发开始
        barber();customer();
    coend;   // 并发结束


版权声明:本文为weixin_46447549原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。