先决条件 – 进程间通信
问题:这个类比是基于一个有一个理发师的假想理发店。有一个理发店,有一个理发师,一个理发椅,还有n把椅子,如果有顾客可以坐在椅子上等顾客。
- 如果没有顾客,理发师就睡在自己的椅子上。
- 当顾客到达时,他必须叫醒理发师。
- 如果有很多顾客并且理发师正在给顾客剪头发,那么剩下的顾客要么在等候室里有空椅子时等待,要么在没有椅子空着时离开。
解决方案:这个问题的解决方案包括三个信号量。第一个是客户,它计算等候室中存在的客户数量(理发椅上的客户不包括在内,因为他没有在等待)。其次,barber 0 或1 用于判断barber 是空闲还是工作,第三个mutex 用于提供进程执行所需的互斥。在该解决方案中,如果客户数量等于等候室中椅子的数量,则客户有在等候室等候的客户数量的记录,则即将到来的客户离开理发店。
当理发师早上出现时,他执行过程理发师,导致他阻塞信号量客户,因为它最初是 0。然后理发师进入睡眠状态,直到第一个客户出现。
当客户到达时,他执行客户程序,客户获取进入临界区的互斥锁,如果此后另一个客户进入,则第二个将无法进行任何操作,直到第一个释放互斥锁。然后客户检查等候室中的椅子,如果等候的客户少于椅子的数量,则他坐下,否则他离开并释放互斥锁。
如果椅子可用,则客户坐在等候室并增加可变等待值并增加客户的信号量,如果他正在睡觉,这会唤醒理发师。
此时,顾客和理发师都醒了,理发师准备给那个人理发。理发结束后,顾客退出程序,如果等候室里没有顾客,理发师就会睡觉。
睡眠理发师问题的算法:
Semaphore Customers = 0;
Semaphore Barber = 0;
Mutex Seats = 1;
int FreeSeats = N;
Barber {
while(true) {
/* waits for a customer (sleeps). */
down(Customers);
/* mutex to protect the number of available seats.*/
down(Seats);
/* a chair gets free.*/
FreeSeats++;
/* bring customer for haircut.*/
up(Barber);
/* release the mutex on the chair.*/
up(Seats);
/* barber is cutting hair.*/
}
}
Customer {
while(true) {
/* protects seats so only 1 customer tries to sit
in a chair if that's the case.*/
down(Seats); //This line should not be here.
if(FreeSeats > 0) {
/* sitting down.*/
FreeSeats--;
/* notify the barber. */
up(Customers);
/* release the lock */
up(Seats);
/* wait in the waiting room if barber is busy. */
down(Barber);
// customer is having hair cut
} else {
/* release the lock */
up(Seats);
// customer leaves
}
}
}