Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Операционные системы_лекции.doc
Скачиваний:
47
Добавлен:
28.09.2019
Размер:
1.71 Mб
Скачать

3.3.2. Методы реализации взаимных исключений

В [1] приведены основные требования, предъявляемые к критическим секциям:

  • в любой момент времени только один процесс должен находиться в своей критической секции;

  • продолжительность нахождения процесса в критической секции не может быть бесконечно долгой;

  • ни один процесс не должен бесконечно долго ожидать разрешения вхождения в свою критическую секцию, для чего должно обеспечиваться выполнение правил:

      • процесс, работающий вне своей критической секции не должен блокировать критическую секцию другого процесса;

      • принятие решения о порядке вхождения в критическую секцию процессов, конкурирующих за критический ресурс, не должно быть бесконечно долгим;

  • если процесс, находящийся в критической секции завершён естественным или аварийным путём, то режим взаимного исключения должен быть отменён.

Эти требования могут быть реализованы множеством средств, описанных Дейкстрой в [4] ещё в 1972 г. К ним относятся:

  • блокировка памяти;

  • специальные команды типа "проверка и установка";

  • средства, предоставляемые системой управления прерываниями:

      • семафорные операции;

      • мониторы;

      • почтовые ящики, конвейеры и очереди сообщений.

3.3.3. Блокировка памяти

Все вычислительные машины и системы поддерживают блокировку памяти, запрещающую одновременное обращение к одной и той же ячейке памяти двух и более команд. Однако механизм блокировки памяти не исключает чередование поочерёдный доступ к ячейке памяти двух и более процессов. Для обеспечения чередование доступа процессов к общей переменной, расположенной в памяти возможны три варианта:

  • применение одной общей переменной (переключателя);

  • применение двух общих переменных;

  • применение двух общих переменных с усилением взаимных исключений;

  • применение трёх общих переменных (алгоритм Декера).

Применение одной общей переменной предусматривает создание переменной, называемой "переключателем" и могущей принимать значения 1 или 2. Значение переключателя равное единице разрешает выполнение секции CS1 (рис. 3.2), а значение переключателя равное двум – выполнение секции CS2. Выполнение критической секции одного процесса не блокирует выполнение обычной секции другого.

В начальный момент запуска процессов переключатель ставится в состояние единица. При этом процесс Р1 выполняет критическую секцию PS1, а процесс Р2 – секцию PR2. Отработав критическую секцию, процесс Р2 ставит переключатель в состояние двойка и переходит к выполнению обычной секции PR1. Процесс Р2 начинает выполнять критическую секцию CS2. После её завершения переключатель устанавливается в положение единица, система приходит в исходное состояние, и всё повторяется.

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

Применение двух переменных предусматривает создание двух общих для процессов Р1 и Р2 логических переменных, которые называются флагами, могут иметь значения True или False. Эти переменные называются переключателями. Далее для определённости рассмотрения реализации взаимного исключения они будут иметь имена "перекл_1" и "перекл_2". Значение True флага перекл_1 означает, что процесс Р1 находится в критической секции CS1, а значение True флага перекл_2 указывает на нахождение в критической секции CS2 процесса Р2.

Перед вхождением в критическую секцию процесс Р1 проверяет состояние флага перекл_2 и, если он имеет значение False, устанавливает свой флаг перекл_1 в состояние True и начинает выполнять свою критическую секцию. После её завершения процесс восстанавливает состояние False флага перекл_1. Если перекл_2 в момент проверки находился в состоянии True, то процесс Р1 мог выполнять обычную секцию или становился в очередь ожидания разрешения на вхождение в критическую секцию. Аналогичным образом действует и процесс Р2, но для него разрешением на вхождение в критическую секцию является значение False флага перекл_1, а управляет он флагом перекл_2.

Такой алгоритм не даёт полной гарантии взаимного исключения, т.к. перевод флагов из одного состояния в другое и вхождение в критическую секцию имеют конечную длительность. За время изменения состояния флага перекл_1 процессом Р1 и вхождения в критическую секцию процесс Р2 (если он имеет более высокое быстродействие) может успеть изменить флаг перекл2 и войти в свою критическую секцию, а процесс Р1 этого не заметит. Возможна и обратная ситуация, если процесс Р1 имеет более высокое быстродействие, чем процесс Р2.

Применение двух переменных с усилением взаимного исключения предусматривает изменение алгоритма работы с переключателями перекл_1 и перекл_2. Усиление взаимного исключение для процесса Р1 сводится к перестановке операций проверки флага перекл_2 и установки флага перекл_1: сначала производится установка флага перекл_1, а после этого проверяется состояние флага перекл_2. Процесс Р2 наоборот, сначала устанавливает флаг перекл_2 и только после этого проверяет состояние флага перекл_1.

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

Алгоритм Декера предусматривает создание трёх переменных перекл_1, перекл_2 и Очередь. Переменные перекл_1 и перекл_2, как и ранее, гарантируют выполнение взаимного исключения. Переменная очередь, указывает какой из процессов, конкурирующих за критический ресурс, должен войти в свою критическую секцию. Переменная очередь не изменяется во время принятия решения о порядке вхождения процессов в критические секции. Её изменение присходит в конце выполнения критической секции. Таким образом, согласно алгоритму Деккера возможны три ситуации вхождения процессами в критические секции:

  • перекл_1=True и перекл_2=False;

  • перекл_1=False и перекл_2=True;

  • перекл_1=True и перекл_2=True и оба процесса желают сойти в критическую секцию.

В первой ситуации право входа в критическую секцию имеет процесс Р1 независимо от значения переменной очередь, во второй ситуации право входа в критическую секцию принадлежит процессу Р2, а в третьей право входа процессов в критическую секцию определяет значение переменной очередь.

Алгоритм Декера для двух процессов гарантирует безошибочную реализацию взаимного исключения, однако имеет чрезмерную сложность при обобщении на произвольное число параллельных процессов.

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