Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Глава_6.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
2 Мб
Скачать
☆

Мьютексы

Одним из вариантов семафорных механизмов для организации взаимного ис­ключения являются так называемые мьютексы (mutex). Термин mutex произо­шел от английского словосочетания mutual exclusion semaphore, что дословно и переводится как семафор взаимного исключения. Мьютексы реализованы во многих ОС, их основное назначение — организация взаимного исключения для задач (потоков) из одного и того же или из разных процессов. Мьютексы — это простейшие двоичные семафоры, которые могут находиться в одном из двух состояний — отмеченном или неотмеченном (открыт и закрыт соответственно). Когда какая-либо задача, принадлежащая любому процессу, становится владель­цем объекта mutex, последний переводится в неотмеченное состояние. Если за­дача освобождает мьютекс, его состояние становится отмеченным.

Организация последовательного (а не параллельного) доступа к ресурсам с ис­пользованием мьютексов становится несложной, поскольку в каждый конкрет­ный момент только одна задача может владеть этим объектом. Для того чтобы объект mutex стал доступен задачам (потокам), принадлежащим разным про­цессам, при создании ему необходимо присвоить имя. Потом это имя нужно пе­редать «по наследству» задачам, которые должны его использовать для взаимо­действия. Для этого вводятся специальные системные вызовы (CreateMutex), в которых указываются начальное значение мьютекса, его имя и, возможно, атрибуты защиты. Если начальное значение мьютекса равно true, то считается, что задача, создающая этот объект, будет им сразу владеть. Можно указать в ка­честве начального значение false — в этом случае мьютекс не принадлежит ни од­ной из задач и только специальным обращением к нему можно изменить его со­стояние.

Для работы с мьютексом имеется несколько функций. Помимо уже упомянутой функции создания такого объекта (CreateMutex), есть функции открытия (Ореп-Mutex), ожидания событий (WaitForSingleObject и WaitForMultipleObjects) и, наконец, освобождение этого объекта (ReleaseMutex).

Конкретные обращения к этим функциям и перечни передаваемых и получае­мых параметров нужно смотреть в документации на соответствующую ОС.

Использование семафоров при проектировании взаимодействующих вычислительных процессов

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

Задача «поставщик — потребитель»

Решение задачи «поставщик - потребитель» является характерным примером использования семафорных операций. Содержательная постановка этой задачи уже была нами описана в первом разделе данной главы. Разделяемыми перемен­ными здесь являются счетчики свободных и занятых буферов, которые должны быть защищены со стороны обоих процессов, то есть действия по посылке и по­лучению сообщений должны быть синхронизированы. Использование семафоров для решения данной задачи приведено в листинге 6.11.

Листинг 6.11. Решение задачи «поставщик — потребитель»

var 5_свободно,5_заполнено.5_вэаимоискл : semaphore; begin

InitSem(S_CBo6oflHO.N); 1пП5ет(5_залолнено.О): 1пН5ет($_взаимоискл,1); parbegin

ПОСТАВЩИК: while true do begin

{ приготовить сообщение } Р(5_свободно); Р(5_взаимоискл);

( послать сообщение } \К5_заполнено): У(5_взаимоискл); end and

ПОТРЕБИТЕЛЬ: while true do begin

Р(5_заполнено): Р(5_взаииоискл):

{ получить сообщение } V(S_ceo6oflHo): У(5_взаимоискл):

{ обработать сообщение } end pa rend end.

Здесь переменные 5_свободно, 5_заполнено являются числовыми семафорами, 5_взаиноискл - двоичный семафор. 5_свободно имеет начальное значение, рав­ное N, где N - количество буферов, с помощью которых процессы связываются. Предполагается, что в начальный момент количество свободных буферов рав­но N; соответственно, количество занятых равно нулю. Двоичный семафор S вэаи-моискл гарантирует, что в каждый момент только один процесс сможет работать с критическим ресурсом, выполняя свой критический интервал. Семафоры 5_сво-бодно и 5_заполнено используются как счетчики свободных и заполненных буфе­ров, i

Действительно, перед посылкой сообщения «поставщик» уменьшает значение 5_свободно на единицу в результате выполнения Р(5_свободно), а после посылки сообщения увеличивает значение 5_заполненО на единицу в результате выпол­нения У(5_эаполнено). Аналогично, перед получением сообщения «потребитель» уменьшает значение 5_заполнено в результате выполнения Р(5_заполнено), а после получения сообщения увеличивает значение 5_свободно в результате выполнения У(5_свободно). Семафоры 5_заполнено, 5_свободно могут также использоваться для блокировки соответствующих процессов. Если пул буферов оказался пустым и к нему первым обратится процесс «потребитель», он заблокируется на семафоре 5_заполнено в результате выполнения Р(5_заполнено). Если пул буферов заполнен и к нему в этот момент обратится процесс «поставщик», то он будет заблокиро­ван на семафоре 5_свободно в результате выполнения Р(5_свободно). В решении задачи о «поставщике» и «потребителе» общие семафоры применены для учета свободных и заполненных буферов. Их можно также применить и для распределения иных ресурсов.

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