C语言中的睡眠理发师问题解决方案
沉睡的理发师困境是由Dijkstra在1965年首次提出的。这个问题是基于一个虚构的情况,在一个理发店里有一个理发师。在理发店中,等待区和工作间是分开的。顾客可以在等待区的n个座位上等待;但是在工作间里只有一把理发椅。
流程间沟通
虽然一个合作的进程可能会受到正在运行的其他进程的影响,但一个独立的进程不受其他进程执行的影响。尽管有可能认为独立运行的进程会非常有效地运作,但确实有许多情况下可以利用合作的性质来提高计算速度、便利性和灵活性。进程可以通过一种叫做进程间通信(IPC)的技术相互作用并协调其操作。这些进程之间的通信可以被认为是一种合作的手段。
问题 。
这个问题是基于一个虚构的理发店,只有一个理发师,这是个问题。有一家理发店,有一个理发师,有一把理发师用的椅子,还有n个座位用来等待客户坐到椅子上,如果有的话。
- 如果没有客户,理发师会在自己的椅子上睡着。
- 当有客户出现时,他需要唤醒理发师。
- 如果等待区有空位,剩下的顾客可以等待,或者当顾客众多,理发师正在为顾客理发时,如果没有空椅子,他们可以离开。
解决方案 。
在解决这个问题的过程中,使用了三个信号器。第一个计算等待区的顾客数量,是为顾客服务的(理发师椅子上的顾客不包括在内,因为他没有在等待)。第二个mutex用于给出进程运行所需的互斥,理发师的0或1用于确定理发师是空闲还是工作。客户端会记录当前有多少客户在等待区等待,当这个数字等于该区域的椅子数量时,下一个客户就会退出理发店。
当理发师在早上到达时执行程序理发,迫使他在semaphore客户端上进行阻塞,因为它最初是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
}
}
}
分析 。
当理发师开始工作时,要执行理发程序,他要检查是否有客户准备好了。接到客户的理发要求,如果有人在,就封锁客户的信号。如果没有人要求理发,理发师就会进入睡眠状态。
客户释放互斥,理发师醒来,如果有椅子可用,等待计数器就会增加。然后理发师进入关键部分,获得突变,并开始理发。
客户在理发结束后离开。现在,理发师看一下等待区是否有其他客户在等待理发,或者没有。如果没有,理发师就要去睡觉了。