📜  进程同步中的睡眠理发师问题

📅  最后修改于: 2021-09-28 09:23:46             🧑  作者: Mango

先决条件 – 进程间通信
问题:这个类比是基于一个有一个理发师的假想理发店。有一个理发店,有一个理发师,一个理发椅,还有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
            }
      }
}