Page 117 - 6571
P. 117
– якщо збережено хоча б одне повідомлення. Фактично, якщо
існує порожня клітинка і збережене повідомлення, то операції
deposit та fetch можуть виконуватися одночасно, оскільки
звернення відбуваються до різних комірок масиву і вони не
впливають одне на одного. Проте вимоги щодо синхронізації для
одноелементного і кільцевого буфера однакові. Зокрема,
використання операцій P та V є таким же самим. Єдина
відмінність полягає в тому, що семафор empty ініціалізується
значенням n, а не 1, оскільки в початковому стані існує n
порожніх комірок. Рішення даної задачі показано в лістингу 19.
Лістинг 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);
...
}
}
У лістингу 19 семафори грають роль лічильників ресурсів.
Кожен враховує кількість елементів ресурсу. Змінна empty –
кількість порожніх комірок буфера, a full – заповнених. Коли
116