Page 145 - 6571
P. 145
Змінна wake_time є локальною по відношенню до тіла фун-
кції delay, а отже, кожен процес, що викликає функцію delay,
обчислює власне значення часу запуску. Далі процес очікує, поки
процедура tick не буде викликана необхідне число раз. Для цьо-
го використовується цикл while з умовою виходу wak-
e_time >= tod. У тілі процедури tick відбувається нарощення
значення змінної tod і запуск призупинених процесів.
Залишається реалізувати синхронізацію між призупиненими
процесами і процесом, що викликає процедуру tick. Один із ме-
тодів полягає у використанні окремої умовної змінної для кожної
умови затримки. Оскільки призупинені процеси можуть перебу-
вати в режимі очікування різні проміжки часу, то кожному з них
потрібна власна умовна змінна. Перед зупинкою процес записує у
власну змінну час, через який він повинен бути запущений. Під
час виклику процедури tick перевіряються умовні змінні і при
необхідності запуску процесу для його змінної генерується сиг-
нал пробудження. Описаний підхід необхідний для вирішення
деяких задач, але він є досить складний і менш ефективний, ніж
необхідно для реалізації монітора Timer.
Необхідну синхронізацію набагато простіше реалізувати, ви-
користовуючи одну умовну змінну і метод так званої покриваю-
чої умови. Логічний вираз, пов’язаний з умовною змінною, «пок-
риває» умови запуску для всіх очікуючих процесів. Коли будь-
яка із покриваючих умов виконується, то запускаються всі очі-
куючі процеси. Після цього, кожен процес також перевіряє влас-
ну умову і залежно від її задоволення поновлює своє виконання
або переходить знову в режим очікування.
У моніторі Timer необхідне використання тільки однієї умо-
вної змінної check, що пов’язана із покриваючою умовою «зна-
чення змінної tod збільшено». Процеси очікують зміни значення
змінної check в тілі функції delay. Під час кожного виклику
процедури tick запускаються всі очікуючі процеси. Описаний
алгоритм роботи монітора Timer показаний в лістингу 28. У про-
цедурі tick для запуску всіх призупинених процесів використо-
вується операція сповіщення signal_all.
144