Page 73 - 4868
P. 73
71 Ошибка! Стиль не определен.
неподільним чином, кожен оператор await можна замінити циклом while,
який повторюється, поки умова закінчення затримки має значення «хиба».
Таким чином, отримуємо дрібномодульний алгоритм розриву вузла
представлений в лістингу1.8.
У даній програмі вирішується проблема критичних секцій для двох
процесів. Таку ж основну ідею можна використовувати для вирішення задачі
при будь-якому числі процесів. Зокрема, для кожного з n процесів протокол
входу повинен складатися з циклу, який проходить n-1 етапів. На кожному
етапі використовуються екземпляри алгоритму розриву вузла для двох
процесів, щоб визначити, які процеси проходять на наступний етап. Якщо
гарантується, що всі n-1 етапів може пройти не більше, ніж один процес, то
в критичній секції одночасно буде знаходитися не більше одного процесу.
Лістинг 1.8– Алгоритм розриву вузла для двох процесів
(дрібномодульне ршення)
bool in1 = false, in2 = false;
int last = 1;
process CS1 {
while (true) {
last = 1;
in1 = true; /* протокол входу */
while (in2 and last == 1) skip;
критична секція;
in1 = false; /* протокол виходу */
некритична секція;
}
}
process CS2 {
while (true) {
last = 2; in2 = true; /* протокол входу */
while (in1 and last == 2) skip;
критична секція;
in2 = false; /* протокол виходу */
некритична секція;
}
}
Нехай in[1: n] та last[1: n] – цілочисельні масиви. Значення
елемента in[i] вказує на номер етапу, який виконує процес CS[i].
Значення last[j] вказує на номер етапу, який останнім почав виконувати
етап CS[j]. Підхід з використанням данихзмінних представлено в лістингу
1.9. Зовнішній цикл for виконується n-1 раз. Внутрішній цикл for процесу
CS[i] перевіряє всі інші процеси. Процес CS[i] очікує, якщо деякий інший
процес знаходиться на етапі з рівним або більшим номером етапу, а процес
CS[i] був останнім процесом, що досягнув етапу j. Як тільки етапу j
досягне ще один процес, або всі процеси «перед» процесом CS[i] вийдуть із