Page 117 - 4868
P. 117

115                                                              Ошибка! Стиль не определен.

                         tod = tod+1;
                         while (!empty(check) && minrank(check) <= tod)
                         signal(check);
                       }
                     }

                     Тепер  у  процедурі  delay  відсутній  цикл  while,  оскільки  процедура
               tick  запускає  процес  тільки  при  задоволені  його  умови  запуску.  Однак
               операцію  signal  у  процедурі  tick  потрібно  помістити  в  цикл,  оскільки
               одного і того ж часу запуску можуть очікувати декілька процесів.

                     16.3. Задача про сплячого перукаря

                     У  якості  останнього  базового  прикладу  розглянемо  ще  одну  класичну
               задачу  синхронізації,  а  саме  задачу  про  сплячого  перукаря.  У  неї  досить
               колоритна умова, як і у задачі про філософів, що обідають. Вона представляє
               собою  практичну  задачу,  наприклад  планування  роботи  голівки  дискового
               накопичувача. Дана задача ілюструє важливість взаємозв’язків клієнт-сервер,
               які  часто  існують  між  процесами.  Для  її  вирішення  необхідний  особливий
               тип  синхронізації,  що  називається  рандеву  (рандеву  –  наперед  обумовлене
               побачення,  призначене  на  певний  час  і  в  певному  місці).  Нарешті,  вона
               прекрасно  демонструє  необхідність  систематичного  підходу  до  вирішення
               задач синхронізації.
                     Формулювання  задачі  про  сплячого  перукаря  має  наступний  вигляд:  у
               тихому  містечку  існує  перукарня  з  двома  дверима  і  декількома  кріслами.
               Відвідувачі входять через одні двері і виходять через інші. Салон перукарні
               малий, і ходити по ньому може тільки перукар та один відвідувач. Перукар
               все життя обслуговує відвідувачів. Коли в салоні нікого немає, то він спить у
               своєму  кріслі.  Коли  відвідувач  приходить  і  бачить  сплячого  перукаря,  він
               будить  його,  сідає  в  крісло  і  спить,  поки  той  зайнятий  стрижкою.  Якщо
               перукар зайнятий, коли приходить відвідувач, то той сідає в одне із вільних
               крісел  і  засинає.  Після  стрижки  перукар  відкриває  відвідувачу  двері  для
               виходу  і  закриває  їх  за  ним.  Якщо  існують  відвідувачі,  що  очікують  на
               стрижку, то перукар будить одного із них і очікує, поки той не сяде в крісло
               перукаря.  Якщо  нікого  немає,  то  він  знову  засинає  до  приходу  наступного
               відвідувача.
                     Відвідувачі  і  перукар  є  процесами,  що  взаємодіють  між  собою  в
               моніторі-перукарні (рис. 1.19). Відвідувачі – це клієнти, які запитують сервіс
               (стрижку)  у  перукаря.  Перукар  –  це  сервер,  який  постійно  надає  їм  сервіс.
               Даний тип взаємодії являє собою приклад відносин клієнт-сервер.
                     Для  реалізації  описаних  взаємодій  перукарню  можна  промоделювати
               монітором  в  якому  наявно  три  процедури:  get_haircut  (постригтися),
               get_next_customer  (покликати  наступного)  і  finished_cut  (закінчити
               стрижку).  Відвідувачі  викликають  процедуру  get_haircut.  Вихід  з  неї

               відбувається  після  того,  як  перукар  закінчить  стрижку  відвідувача,  що
               викликав        процедуру.        Перукар        циклічно        викликає        процедуру
   112   113   114   115   116   117   118   119   120   121   122