Page 116 - 4868
P. 116
Ошибка! Стиль не определен. 114
в лістингу 1.28. У процедурі tick для запуску всіх призупинених процесів
використовується операція сповіщення signal_all.
Лістинг 1.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);
}
}
Проте, компактне і просте рішення, представлене в лістингу 1.28 не є
достатньо ефективним для вирішення даної задачі. Застосування методу
покриваючих умов виправдане тільки в ситуаціях, коли витрати на обробку
хибних сигналів (запускається процес, який визначає, що його умова хибна, і
відразу ж повертається в стан очікування) менші, ніж витрати на
обслуговування умов усіх очікуючих процесів і запуск тільки того процесу,
для якого умова задовольняється. Зазвичай саме так і буває, але ймовірно, що
процеси призупиняють своє виконання на тривалий час і, отже, буде
виконуватися їх багаторазовий запуск та призупинення.
Використовуючи пріоритетний операторwait, можна перетворити
програму представлену в лістингу 1.28 в більш просте та ефективне рішення.
Для цього використовується пріоритетний оператор wait скрізь, де є
статична впорядкованість умов для різних очікуючих процесів. У даній
ситуації очікуючі процеси можна впорядкувати за часом їх запуску. Для
цього у процедурі tick, щоб визначити, чи прийшов час запустити перший
процес використовується функція minrank. Нова версія монітора Timer, що
задовольняє даним поправкам представлена у лістингу 1.29.
Лістинг 1.29– Інтервальний таймер з пріоритетним очікуванням
monitor Timer {
int tod = 0;
cond check; # отримує сигнал, коли minrank(check) <= tod
procedure delay(int interval) {
int wake_time;
wake_time = tod + interval;
if (wake_time > tod) wait(check, wake_time);
}
procedure tick() {