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

22Проблема ограниченного буфера

С этой задачей мы уже встречались, рассматривая схему «производитель-потребитель». Она обычно используется для иллюстрации возможностей примитивов синхронизации. Представим общую структуру этой схемы, не вдаваясь в детали реализации.

Считаем, что буфер имеет емкость n элементов. Семафор mutex используется для организации взаимно исключаемого доступа к буферу и инициализирован значением 1. Семафоры empty и full подсчитывают число пустых и заполненных элементов буфера, соответственно. Начальное значение empty равно n, а начальное значение full – 0.

Общая схема работы производителя и потребителя представлена ниже.

Производитель:

repeat

. . .

produce an item ti nextp

. . .

wait(empty);

wait(mutex);

. . .

add nextp to buffer

. . .

signal(mutex);

signal(empty);

. . .

until false;

Потребитель

repeat

. . .

wait(full)

wait(mutex);

. . .

remove an item from buffer to nextc

. . .

signal(mutex);

signal(full);

. . .

consume the item in nextc

. . .

until false;

Заметим очевидную симметрию решения.

23Проблема читателей и писателей

Данные (например, файлы или записи) могут разделяться между несколькими параллельными процессами. Некоторые из этих процессов могут только считывать содержимое данных, в то время как другие процессы могут их изменять. Подчеркнем различие между двумя этими типами процессов, назвав первые читателями, а вторые – писателями. Легко видеть, что два читателя могут иметь доступ к данным одновременно безо всякого ущерба. Однако писатель и любой другой процесс не должны иметь такой возможности, так как это может привести к хаосу. Чтобы избежать подобных трудностей, потребуем, чтобы писатель имел исключительный доступ к разделяемому объекту.

Задача синхронизации носит название задачи о читателях и писателях. Она имеет несколько вариантов. Простейший вариант, известный как первая задача о читателях и писателях, требует, чтобы ни один читатель не попадал в состояние ожидания, если другие читатели имеют доступ к объекту, из-за того, что писатель затребовал доступ к нему. Вторая задача о читателях и писателях требует, чтобы писатель, напротив, получил доступ к объекту как можно скорее. То есть, если писатель ждет, то ни один новый читатель не может начать чтение.

Заметим, что решение каждой из задач может привести к зависанию. В первом случае могут зависать писатели, а во втором читатели.

Рассмотрим решение первой задачи. В этом решении используются следующие структуры данных:

var mutex, wrt: semaphore;

readcount: integer;

Первоначально семафоры установлены в 1, а переменная readcount в 0. Семафор mutex используется для организации взаимного исключения на момент изменения переменной readcount. Переменная readcount обозначает число процессов, читающих объект в данный момент. Переменная wrt используется для взаимного исключения писателей.

Писатель:

wait(wrt);

. . .

writing is performed

. . .

signal(wrt);

Читатель:

wait(mutex);

readcount := readcount + 1;

if readcount = 1 then

wait(wrt);

signal(mutex);

. . .

reading is performed

. . .

wait(mutex);

readcount := readcount - 1;

if readcount = 0 then

signal(wrt);

signal(mutex);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]