Page 83 - 4868
P. 83
81 Ошибка! Стиль не определен.
arrive[i] = 1;
<await (continue[i] == 1);>
Процес Coordinator очікує, поки всі елементи масиву arrive не
стануть рівні 1, а потім присвоює значення 1 всім елементам масиву
continue.
for [i = 1 to n] < await (arrive[i] == 1);>
for [i = 1 to n] continue[i] = 1;
Оператори await можна реалізувати у вигляді циклів while, оскільки
кожен із них посилається лише на одну спільну змінну. У процесі
Coordinator для очікування процедури присвоєння значень всім елементам
arrive можна використати оператор for. Оскільки для продовження роботи
процесів Worker повинні бути встановлені значення для усіх елементів
масиву arrive, то процес Coordinator може перевіряти їх у довільному
порядку. Конфліктів звернення до пам’яті тепер не буде, оскільки процеси
очікують зміни різних змінних, кожна з яких може зберігатися у своєму
рядку кеш-пам’яті.
Змінні arrive та continue в представлених програмах є прикладами
так званого прапорця. Його встановлює (піднімає) один процес, щоб
повідомити іншого про виконання умови синхронізації. Доповнимо програми
кодом, який скидає прапорці (присвоюючи їм значення 0) для підготовки їх
до наступної ітерації. При цьому використовуються два основних правила
синхронізації за допомогою прапорців: 1) прапорець синхронізації скидається
тільки процесом, який очікує його установки; 2) прапорець не можна
встановлювати до тих пір, поки не відомо точно, що він скинутий.
Перше правило гарантує, що прапорець не буде скинутий, поки процес
не визначить, що він встановлений. Відповідно з цим правилом, прапорець
continue[і] повинен скидатися процесом Worker[і], а обнуляти всі
елементи масиву arrive повинен процес Coordinator. Згідно з другим
правилом процес не встановлює прапорець до того часу, поки він не
скинутий іншим процесом. В потилежному випадку, якщо інший
синхронізований процес очікує повторної установки прапорця, то можлива
ситуація взаємного блокування. Це означає, що процес Coordinator
повинен скинути значення arrive[і] перед установкою значення змінної
continue[і]. Процес Coordinator може зробити це, виконавши ще один
оператор for після першого оператора for. Також процес Coordinator
може скинути значення arrive[і] відразу після того, як дочекається його
установки. Додавши код скидання прапорців, отримаємо бар’єр з керуючим
процесом (лістинг 1.14).
Лістинг 1.14– Бар’єрна синхронізація з керуючим процесом
int arrive[1: n] = ([n] 0), continue[1: n] = ([n] 0);
process Worker[i = 1 to n] {
while (true) {