Page 119 - 4868
P. 119
117 Ошибка! Стиль не определен.
Нарешті, відвідувачі не можуть виходити з перукарні раніше, ніж
перукар завершить стрижку:
С3: cleave <= bdone
Інваріант монітора для перукарні, таким чином перетворюється в
кон’юнкцію трьох предикатів:
BARBER: C1 C2 C3
Значення лічильників, що використовуються для запам’ятовування
етапів через які проходять процеси, не можуть зростати безмежно, оскільки
вони лежать в діапазоні значень типів змінних. Якщо б синхронізація
залежала тільки від різниці між значеннями лічильників, то безмежного
зростання можна було б уникнути. У описаній задачі можна виділити три
ключові змінні з іменами barber, chair та open.
barber == bavail – cinchair;
chair == cinchair – bbusy;
open == bdone – cleave;
Вони ініціалізуються нульовими значеннями, а під час роботи програми
можуть приймати значення 0 або 1. Значення змінної barber рівне 1, якщо
перукар очікує відвідувача і сидить у своєму кріслі. Змінна chair має
значення 1, якщо відвідувач вже сів у крісло, але перукар ще не почав
стрижку, а змінна open приймає значення 1, якщо двері для виходу вже
відчинені, але відвідувач ще не вийшов.
Використаємо описані вище умовні змінні для реалізації необхідної
синхронізації між перукарем та відвідувачами. Існують чотири умови
синхронізації: 1) відвідувачі очікують звільнення перукаря; 2) відвідувачі
очікують, коли перукар відкриє двері; 3) перукар очікує приходу відвідувача;
4) перукар очікує, коли відвідувач покине перукарню. Для представлення
даних умов необхідно чотири умовні змінні. Процеси очікують виконання
умов за допомогою операторів wait, що знаходяться в циклах. У момент,
коли умови задовольняють істині, процеси виконують операцію signal.
Повне рішення задачі про сплячого перукаря представлено в лістингу 1.30.
Лістинг 1.30 – Реалізація монітора для задачі про сплячого перукаря
monitor Barber_Shop {
int barber = 0, chair = 0, open = 0;
cond barber_available; # отримує сигнал, коли barber > 0
cond chair_occupied; # отримує сигнал, коли chair > 0
cond door_open; # отримує сигнал, коли open > 0
cond customer_left; # отримує сигнал, коли open == 0
procedure get_haircut() {
while (barber == 0) wait(barber_available);
barber = barber-1;
chair = chair+1;
signal(chair_occupied);