信号量设置

「睡眠理发师问题」是信号量的一个典型例子,问题描述如下

理发店里有一位理发师、一把理发椅和 把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉。一个顾客到来时,它必须叫醒理发师。如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。

对于此问题,显然顾客数 customersbarbers 是需要设置的信号量。此外,由于检查等候顾客数量、等待顾客数加减等操作也是临界区内的,因此还需要设置一个 mutex

  • customers 表示店里顾客的数量,初值为 0
  • barbers 初值为 0
  • mutex 表示临界资源,初值为 1

代码

初始化

int waiting=0; /*等候理发顾客坐的椅子数*/
int CHAIRS=N; /*为顾客准备的椅子数*/
semaphore customers,barbers,mutex;  
customers=0;barbers=0;mutex=1;

对于理发师

cobegin
	process barber( ) {
		while(true) {
			P(customers);/*有顾客吗?若无顾客,理发师睡眠*/
			P(mutex); /*若有顾客时,进入临界区*/
			waiting--; /*等候顾客数少一个*/
			V(barbers); /*理发师准备为顾客理发*/
			V(mutex); /*退出临界区*/
			cut_hair(); /*理发师正在理发(非临界区)*/
		}
	}
	process customer_i( ) {
		P(mutex); //进入临界区
		if(waiting<CHAIRS) { //有空椅子吗
			waiting++; //等候顾客数加1
			V(customers); //唤醒理发师
			V(mutex); //退出临界区
			P(barbers); //理发师忙,顾客坐下等待
			get_haircut(); //否则顾客坐下理发
		}
		else
			V(mutex); //人满了,走吧!
	}
coend