Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Операційні системи.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
6.41 Mб
Скачать

Алгоритм «в пиріжковій» (bakery algorithm)

Автор даного алгоритму - Л. Лампорт (L. Lamport). Розглянемо інший алгоритм, що вирішує проблему синхронізації по критичних секціях. Походження назви наступне: алгоритм як би відтворює стратегію автомата в (американської) булочній, де кожному клієнтові привласнюється його номер у черзі. По побудові, номер, що привласнюється процесу, буде гарантовано більше, ніж номер будь-якого іншого процесу в системі. Перш ніж увійти в критичну секцію, процес чекає, поки завершиться процес вибору номера для всіх процесів і поки в системі є хоча б один обраний процес, номер якого менше. По закінченні критичної секції процес обнуляє свій номер. Даний алгоритм також вирішує проблему синхронізації процесів по критичних секціях.

Синхронізація на основі загальних семафорів

Ми вже почали розглядати семафори Дейкстра як засіб синхронізації в оглядовій частині курсу. Тут ми розглянемо їх більш докладно в загальному виді. Загальний семафор (counting semaphore), по Е. Дейкстру, - це ціла змінна S, над якою визначені дві атомарних семафорних операції wait (S) і signal (S) з наступною семантикою:

wait (S):

while (S <= 0) do no-op;

S--;

signal (S):

S++;

Фактично, якщо початкове значення загального семафора дорівнює n (> 0), те це число задає кількість процесів, які можуть безперешкодно виконати над семафором операцію wait.

Синхронізація по критичних секціях за допомогою загального семафора здійснюється в такий спосіб:

/* загальні дані */

semaphore mutex = 1;

do {

wait (mutex);

критична секція

signal (mutex);

інша частина коду

} while (1)

Реалізація семафорів

Семафор, власне кажучи, є структурою із двох полів - цілого значення й покажчика на список процесів, що чекають:

typedef struct {

int value;

struct process * L;

} semaphore;

При реалізації операцій над семафором будемо припускати наявність у системі наступних найпростіших примітивів і використати їх:

block - затримує виконання процесу, що виконав цю операцію;

wakeup (P) - відновляє виконання припиненого процесу P.

Визначимо семафорні операції в такий спосіб:

wait (S):

S.value-і;

if (S.value < 0) {

додавання поточного процесу до S.L;

block;

}

signal (S):

S.value++;

if (S.value <= 0) {

видалення процесу P з S.L;

wakeup (P);

}

Семафори як загальний засіб синхронізації

Загальні й двійкові семафори

Є два види семафорів: загальний - ціла змінна з теоретично необмеженим значенням - і двійковий - ціла змінна, значеннями якої можуть бути тільки 0 або 1. Перевагою двійкового семафора є його можлива більше проста апаратна реалізація. Очевидно, що загальний семафор може бути реалізований за допомогою двійкового семафора.

Рішення класичних завдань синхронізації за допомогою семафорів

Завдання "обмежений буфер".Є три класичних завдання синхронізації процесів:

  • обмежений буфер (bounded buffer problem)

  • читачі - письменники (readers - writers problem)

  • філософи, що обідають (dining philosophers problem).

.

Рішення за допомогою семафорів завдання

Розглянемо реалізацію за допомогою семафорів завдання обмежений буфер: є процес-виробник і процес-споживач, взаємодіючі за допомогою циклічного буфера обмеженої довжини; виробник генерує елементи інформації й записує в буфер; споживач використовує інформаційні елементи з буфера й видаляє їх.

Семафор mutex використається "симетрично"; над ним виконується пара операцій: wait ... signal - семафорні дужки. Його роль - чисто взаємне виключення критичних секцій. Семафор empty сигналізує про вичерпання буфера. На початку він закритий, тому що елементів у буфері немає. Тому при закритому семафорі empty споживач змушений чекати. Відкриває семафор empty виробник, після того, як він записує в буфер черговий елемент. Семафор full сигналізує про переповнення буфера. На початку він дорівнює n - максимальному числу елементів у буфері. Виробник перед записом елемента в буфер виконує операцію wait (full),гарантуючи, що, якщо буфер переповнений, запису нового елемента в буфер не буде. Відкриває семафор full споживач, після того, як він звільнив черговий елемент буфера.