Здравствуйте!
В данной лекции рассмотрим возможные
способы организации синхронизации,
а так же разберем как их сильные, так и слабые стороны.
Способы синхронизации процессов довольно различны.
Например, первый способ, о котором хотелось бы сказать —
это блокировка памяти.
Все вычислительные системы имеют основную
форму аппаратной реализации взаимного исключения,
называемую блокированием памяти.
Это средство запрещает одновременное исполнение двух
и более команд, которые обращаются
к одной и той же ячейке памяти.
В случае если в этой ячейке хранится
значение разделяемой переменной,
то получить доступ к ней может только один процесс.
Следующий способ — запрещение прерываний.
Процесс, использующий критический ресурс,
должен блокировать обработку всех прерываний,
поступающих на вычислительной системе.
Он выходит из-под контроля операционной системы
и становится монопольным "хозяином"
центрального процессора до тех пор, пока
сам не освободит систему прерываний.
Поскольку на интервале между блокированием
и разблокированием прерываний ни один процесс,
кроме захватившего ресурс
не может выполняться, решается задача взаимного исключения.
Но есть негативные стороны данного решения.
Механизм негибкий в силу простоты,
имеет низкую эффективность
(требуется значительные усилия для решения
других задач синхронизации, отличных от взаимного исключения).
При длительных временах использования
критических участков и частом обращении
к ним мультипрограммный режим работы
вычислительной системы может быть нарушен
(не будут выполняться другие процессы)
и приблизится к однопроцессному режиму.
Негативных сторон можно избежать, в случае если
ввести еще один элемент при обращении к критическому ресурсу:
переменную состояния, которая могла бы в любой момент
времени характеризовать состояние критического ресурса.
Эта переменная должна быть доступна всем процессам,
использующим данный ресурс.
Процессы могут как читать, так и изменять ее состояние
(она сама становится критическим ресурсом).
Чтобы захватить основной критический ресурс
крайне важно предварительно захватить
вспомогательную переменную состояния.
Для реализации вспомогательного критического интервала
можно воспользоваться блокированием прерываний,
но длительность этой области будет мала
(только проверить и установить, в случае
если это допустимо, переменную состояния).
Тогда проблема взаимного исключения решается в три этапа.
Выполняется вспомогательный критический интервал
(при этом блокируются прерывания).
В случае если переменная состояния показывает
на незанятость основного критического ресурса,
то значение переменной меняется на "занято"
и переходят ко второму этапу.
Процесс переходит в основной критический интервал.
Нет крайней важности блокировать прерывания,
так как гарантом взаимного исключения
является переменная состояния.
Выполняется вспомогательный критический интервал
(при этом блокируются прерывания).
Значение переменной состояния меняется на "не занято".
Вспомогательные критические интервалы на этапах 1 и 3
являются неделимыми взаимоисключаемыми
примитивами для решения задач взаимного исключения.
В случае если на первом этапе обнаруживается,
что критический ресурс занят,
то используются два решения.
Режим "занятого" ожидания.
Процесс повторно и периодически организует
сам или с помощью системы
проверку освобождения ресурса
(выполняет вспомогательный критический интервал).
Режим "пассивного" ожидания.
Организуется очередь процессов.
В состав механизма синхронизации
включаются средства для решения задач управления очередью.
Существует множество вариантов решения данной задачи.
Третий способ — синхронизация процессов
посредством операции "проверка и установка".
Такая операция является, как
и блокировка памяти, одним из аппаратных
средств решения задачи критического интервала.
Данная операция реализована на многих компьютерах.
Команда проверки является аппаратно-поддерживаемой
составной командой. Но при этом она является
неделимой операцией, то есть между ее началом
и концом не могут выполняться никакие другие команды.
F от D — это функция, блокирующая переменный ресурс D
(0 — свободен, 1 — занят).
Как происходит выполнение команды?
Перед входом в критический интервал процесс
выполняет команду TS.
Циклически проверяется F(D) = 0
(это часть команды проверки).
В случае если F(D) = 0, то F(D) = 1
(это команда установка).
Процесс входит в критическую секцию.
После выполнения критической секции F(D)
снова становится равным 0.
Блокирующие переменные могут использоваться
не только при доступе к разделяемым данным,
но и при доступе к разделяемым ресурсам любого вида.
В случае если все процессы выполняют
вышеописанные соглашения,
то взаимное исключение гарантируется.
При этом процессы бывают прерваны операционной системой
в любой момент времени и в любом месте,
в т. ч. в критическом интервале.
Нельзя прерывать процесс только между
выполнением операций проверки
и установки блокирующей переменной.
Пусть в результате проверки переменной процесс
определил, что ресурс свободен,
но сразу после этого,
не успев установить переменную в 0, был прерван.
За время его приостановки другой процесс занял ресурс,
вошел в свой критический интервал,
но также был прерван,
не завершив работы с разделяемым ресурсом.
Когда управление было возвращено первому процессу,
он, считая ресурс свободным,
установил признак занятости и начал выполнять
свой критический интервал.
Таким образом, был нарушен
принцип взаимного исключения,
что потенциально может привести к нежелательным последствиям.
Во избежание таких ситуаций
в системе команд многих компьютеров
предусмотрена единая, неделимая команда
анализа и присвоения значения логической переменной.
При отсутствии такой команды в процессоре
соответствующие действия должны реализовываться
специальными системными примитивами,
которые бы запрещали прерывания
на протяжении всей операции проверки и установки.