Page 94 - 4868
P. 94
Ошибка! Стиль не определен. 92
споживач»), то виконання операцій deposit та fetch має чергуватися. За
наявності декількох буферів операцію deposit можна виконати, якщо існує
порожня клітинка, a fetch – якщо збережено хоча б одне повідомлення.
Фактично, якщо існує порожня клітинка і збережене повідомлення, то
операції deposit та fetch можуть виконуватися одночасно, оскільки
звернення відбуваються до різних комірок масиву і вони не впливають одне
на одного. Проте вимоги щодо синхронізації для одноелементного і
кільцевого буфера однакові. Зокрема, використання операцій P та V є таким
же самим. Єдина відмінність полягає в тому, що семафор empty
ініціалізується значенням n, а не 1, оскільки в початковому стані існує n
порожніх комірок. Рішення даної задачі показано в лістингу 1.19.
Лістинг 1.19 – Реалізація кільцевого буфера з використанням семафорів
typeT buf[n]; /* буфер типу Т */
int front = 0, rear = 0;
sem empty = n, full = 0; /* N-2 <= empty + full <= n */
process Producer {
while (true) {
...
створити повідомлення data;
/* помістити data в буфер */
P(empty);
buf[rear] = data;
rear = (rear+1) % n;
V(full);
}
}
process Consumer {
while (true) {
/* витягти та видалити повідомлення result */
P(full);
result = buf[front];
front = (front+1) % n;
V(empty);
...
}
}
У лістингу 1.19 семафори грають роль лічильників ресурсів. Кожен
враховує кількість елементів ресурсу. Змінна empty – кількість порожніх
комірок буфера, a full – заповнених. Коли жоден процес не виконує
операції deposit або fetch, сума значень обох семафорів дорівнює
загальному числу комірок n. Виконуючі облік ресурсів семафори
використовуються у випадках, коли процеси конкурують за доступ до таких
багатоелементних ресурсів, як комірки буфера або блоки пам’яті.
У програмі з лістингу 1.19 передбачається, що існує тільки один