Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОС.docx
Скачиваний:
44
Добавлен:
22.09.2019
Размер:
3.18 Mб
Скачать

19. Применение семафоров и мьютексов в задаче о производителях и потребителях. (Лекция 5)

Для организации работы используем три семафора:

Access (mutex) – двоичный семафор для организации взаимоисключения при доступе к хранилищу;

Full – общий семафор, блокирующий поток-производитель при попытке записи сообщения в полностью заполненное хранилище (в переменной семафора будет хранится количество имеющихся свободных мест для сообщений в хранилище);

Empty – общий семафор, блокирующий поток-потребитель при попытке чтения сообщения из пустого хранилище (в переменной семафора будет хранится количество имеющихся сообщений в хранилище).

Возможная реализация взаимоисключения потоков может состоять в следующем.

// Семафор взаимоисключения доступа

Semaphore Access = 1;

// Семафор блокировки записи в полное хранилище

Semaphore Full = n;

// Семафор блокировки чтения из пустого хранилища

Semaphore Empty = 0;

Producer(){

<Генерация нового сообщения>

// Доступ только при наличии пустых мест P(Full);

P(Access); // Блокировка доступа к хранилищу

<Запись сообщения в хранилище>

// Снятие блокировки доступа к хранилищу

V(Access);

// Отметка наличия сообщений в хранилище

V(Empty);

} Consumer(){

// Доступ только при наличии сообщений

P(Empty);

P(Access); // Блокировка доступа к хранилищу

<Чтение сообщения из хранилища>

// Снятие блокировки доступа к хранилищу

V(Access);

// Отметка наличия пустых мест в хранилище

V(Full);

<Обработка полученного сообщения> }

2 способ: Проблему потерянных сигналов запуска можно решить с помощью семафоров. Очень важно, чтобы они были реализованы неделимым образом. Стандартным способом является реализация операций down и up в виде системных запросов, с запретом ОС всех прерываний на период проверки семафора, изменения его значения и возможного перевода процесса в состояние ожидания. Поскольку для

выполнения всех этих действий требуется всего лишь несколько команд процессора, запрет прерываний не приносит никакого вреда. Если используются несколько процессоров, каждый семафор необходимо защитить переменной блокировки с использованием команды TSL, чтобы гарантировать одновременное обращение к семафору только одного процессора. Использование команды TSL принципиально отличается от активного ожидания, при котором производитель или потребитель ждут наполнения или опустошения буфера. Операция с семафором займет несколько микросекунд, тогда как активное ожидание может затянуться на существенно больший промежуток времени.

З начение счетчика full исходно равно нулю, счетчик empty равен числу сегментов в буфере, a mutex равен 1. Семафоры, исходное значение которых равно 1, используемые для исключения одновременного нахождения в критической области двух процессов, называются двоичными семафорами. Взаимное исключение обеспечивается, если каждый процесс выполняет операцию down перед входом в критическую область и up после выхода из нее. Семафор mutex используется для реализации взаимного исключения, то есть для исключения одновременного обращения к буферу и связанным переменным двух процессов. Остальные семафоры использовались для синхронизации. Семафоры full и empty необходимы, чтобы гарантировать, что определенные последовательности событий происходят или не происходят. В нашем случае они гарантируют, что производитель прекращает работу, когда буфер полон, а потребитель прекращает работу, когда буфер пуст.