Page 146 - 6571
P. 146
Лістинг 28 – Інтервальний таймер з покриваючою умовою
monitor Timer {
int tod = 0;
cond check; # отримує сигнал, коли tod збільшено
procedure delay(int interval) {
int wake_time;
wake_time = tod + interval;
while (wake_time > tod) wait(check);
}
procedure tick() {
tod = tod+1;
signal_all(check);
}
}
Проте, компактне і просте рішення, представлене в лістингу
28 не є достатньо ефективним для вирішення даної задачі. Засто-
сування методу покриваючих умов виправдане тільки в ситуаці-
ях, коли витрати на обробку хибних сигналів (запускається про-
цес, який визначає, що його умова хибна, і відразу ж повертаєть-
ся в стан очікування) менші, ніж витрати на обслуговування умов
усіх очікуючих процесів і запуск тільки того процесу, для якого
умова задовольняється. Зазвичай саме так і буває, але ймовірно,
що процеси призупиняють своє виконання на тривалий час і, от-
же, буде виконуватися їх багаторазовий запуск та призупинення.
Використовуючи пріоритетний оператор wait, можна
перетворити програму представлену в лістингу 28 в більш просте
та ефективне рішення. Для цього використовується пріоритетний
оператор wait скрізь, де є статична впорядкованість умов для
різних очікуючих процесів. У даній ситуації очікуючі процеси
можна впорядкувати за часом їх запуску. Для цього у процедурі
tick, щоб визначити, чи прийшов час запустити перший процес
використовується функція minrank. Нова версія монітора Timer,
що задовольняє даним поправкам представлена у лістингу 29.
Тепер у процедурі delay відсутній цикл while, оскільки
процедура tick запускає процес тільки при задоволені його умо-
ви запуску. Однак операцію signal у процедурі tick потрібно
помістити в цикл, оскільки одного і того ж часу запуску можуть
очікувати декілька процесів.
145