- •3 Основные понятия и концепция операционных систем. Режимы работы ос. Системные вызовы
- •4 Архитектура современных операционных систем.
- •5 Процессы. Состояние процесса.
- •6 Контекст и паспорт процесса .
- •7 Концепция и критерии планирования процессов. Уровни планирования
- •8 Стратегии планирования процессов. Критерии планирования и требования к алгоритмам
- •9 Взаимодействие процессов. Адресация средств связи при взаимодействии процессов.
- •10 Алгоритмы синхронизации процессов. Примитивы взаимоисключения.
- •1.Взаимоисключение для n процессов
- •2. Аппаратная реализация взаимоисключения: команда testandset
- •2. Семафоры
- •3. Синхронизация процессов при помощи семафоров
- •11 Достаточное условие детерменированности Беристайна.
- •12 Семафоры. Операция над семафорами.
- •13 Семафоры как средство взаимоисключения.
- •14 Тупики и бесконечные откладывания.
- •15 Система управления процессорами. Компоненты системы.
- •16 Алгоритмы планирования процессов
- •17 Система управления памятью.
- •8.3.1 Схема с фиксированными разделами.
- •18 Виртуальная память. Архитектурные средства поддержки виртуальной памяти. Архитектурные средства поддержки виртуальной памяти
- •Страничная виртуальная память
- •Сегментно-страничная организации виртуальной памяти
- •Структура таблицы страниц
- •19 Управление внешней памятью. Файловые системы. Управление внешней памятью
- •Методы выделения дискового пространства
- •Выделение непрерывной последовательностью блоков
- •Связный список
- •Индексные узлы
- •20 Управление системой ввода-вывода
- •Рис 2. Методы управления периферийными устройствами: а)прямой; б)косвенный
10 Алгоритмы синхронизации процессов. Примитивы взаимоисключения.
1.Взаимоисключение для n процессов
Программное решение проблемы реализации примитивов взаимоисключения для п процессов первым предложил Дейкстра. Затем Кнут усовершенствовал алгоритм Дейкстры, исключив возможность бесконечного откладывания процессов, однако в варианте Кнута некоторый процесс по-прежнему мог испытывать (потенциально) длительную задержку. В связи с этим многие ученые начали искать алгоритмы, обеспечивающие более короткие задержки. Так, Эйзенберг и Макгайр предложили решение, гарантирующее, что процесс будет входить в свой критический участок не более чем за п—1 попыток. Лэмпорт разработал алгоритм, применимый, в частности, для распределенных систем обработки данных. Алгоритм Лэмпорта предусматривает «предварительное получение номерка», подобно тому как это делается в модных кондитерских, и поэтому подучил наименованиеалгоритма кондитера (Bakery Algorithm). Бринк Хансен также предлагает возможные варианты управления параллельными распределенными процессами.
2. Аппаратная реализация взаимоисключения: команда testandset
Алгоритм Деккера — это программное решение проблемы взаимоисключения. В данном разделе мы приводим аппаратное решение данной проблемы.
Главным фактором, обеспечивающим успех в этом случае, является наличие одной аппаратной команды, которая осуществляет чтение переменной, запись ее значения в область сохранения и установку нужного конкретного значения этой переменной. Подобная команда, обычно называемая testandset (проверить-и-установить), после запуска выполняет все эти действия до конца без прерывания. Неделимая команда
testandset (а, b)
читает значение логической переменной b, копирует его в а, а затем устанавливает для b значение «истина» — и все это в рамках одной непрерываемой операции. Пример использования команды проверки и установки для реализации взаимоисключения приведен на рис. 1.
program npимeptestandset var активный: логический;
procedure процессодин;
var первомувходитьнельзя: логический;
begin
while истина do
begin
первомувходитьнельзя : = истина;
while первомувходитьнельзя do
testandset (первомувходитьнельзя, активный);
критическийучастокодин;
активный : = ложь;
прочиеоператорыодин
end
end;
procedure процессдва;
var второмувходитьнельзя: логический;
begin
while истина do
begin
второмувходитьнельзя : = истина;
while второмувходитьнельзя do
testandset (второмувходитьнельзя, активный);
критическийучастокдва;
активный : = ложь;
прочиеоператорыдва
end
end;
begin
активный : = ложь;
parbegin
процессодин;
процессдва parend
end;
Рис. 1. Реализация взаимоисключения при помощи команды testandsef
(ПРОВЕРИТЬ И УСТАНОВИТЬ).
Переменная «активный» логического типа имеет значение «истина», когда любой из процессов находится в своем критическом участке, и значение «ложь» в противном случае. «Процессодин» принимает решение о входе в критический участок в зависимости от значения своей локальной логической переменной «первомувходитьнельзя». Он устанавливает для переменной «первомувходитьнельзя» значение «истина», а затем многократно выполняет команду проверки и установки для глобальной логической переменной «активный». Если «процессдва» находится вне критического участка, переменная «активный» будет иметь значение «ложь». Команда проверки и установки запишет это значение в «первомувходитьнельзя» и установит] значение «истина» для переменной «активный». При проверке в цикле while будет получен результат «ложь», и «процессодин» войдет в свой критический участок. Поскольку для переменной «активный» установлено значение «истина», «процессдва» в свой критический участок войти не может.
Предположим теперь, что «процессдва» уже находится в своем критическом участке, когда «процессодин» хочет войти в критический участок. «Процессодин» устанавливает значение «истина» для переменной «первомувходитьнельзя», а затем многократно проверяет значение переменной «активный» по команде testandset. Поскольку «процессдва» находится в своем критическом участке, это значение остается истинным. Каждая команда проверки и установки обнаруживает, что «активный» имеет значение «истина», и устанавливает это значение для переменных «первомувходитьнельзя» и «активный». Таким образом, «процессодин» продолжает находиться в цикле активного ожидания, пока «процессдва» в конце концов не выйдет из своего критического участка и не установит значение «ложь» для переменной «активный». В этот момент команда проверки и установки, обнаружив это значение переменной «активный» (и установив для нее истинное значение, чтобы «процессдва» не мог больше войти в свой критический участок), установит значение «ложь» для переменной «первомувходитьнельзя», что позволит, чтобы «процессодин» вошел в свой критический участок.
Этот способ реализации взаимоисключения не исключает бесконечного откладывания, однако здесь вероятность такой ситуации весьма мала, особенно если в системе имеется несколько процессоров. Когда процесс, выходя из своего критического участка, устанавливает значение «ложь» переменной «активный», команда проверки и установки testandset другого процесса, вероятнее всего, сможет «перехватить» переменную «активный» (установив для нее значение «истина») до того, как первый процесс успеет пройти цикл, чтобы снова установить значение «истина» для этой переменной.