Parbegin
Команда testandset Это аппаратная команда, которая осуществляет чтение переменной, запись ее значения в область сохранения и установку нужного конкретного значения этой переменной. Подобная команда, обычно называемая testandset (проверить-и-установить), после запуска выполняет все эти действия до конца без прерывания. Поэтому ее называют неделимой командой. testandset (a, b) Ø читает значение логической переменной b, Ø копирует его в a, Ø устанавливает для b значение "истина" и все это в рамках одной непрерываемой операции.
Пример использования команды проверки и установки для реализации взаимоисключения: program примерtestandset 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; Рис. 4.8 Реализация взаимоисключения при помощи команды testandsef (ПРОВЕРИТЬ И УСТАНОВИТЬ) Переменная "активный" логического типа имеет значение "истина", когда любой из процессов находится в своем критическом участке, и значение "ложь" в противном случае. "Процессодин" принимает решение о входе в критический участок в зависимости от значения своей локальной логической переменной "первомувходитьнельзя". Он устанавливает для переменной "первомувходитьнельзя" значение "истина", а затем многократно выполняет команду проверки и установки для глобальной логической переменной "активный". Если "процессдва" находится вне критического участка, переменная "активный" будет иметь значение "ложь". Команда проверки и установки запишет это значение в "первомувходитьнельзя" и установит значение "истина" для переменной "активный". При проверке в цикле while будет получен результат "ложь", и "процесс-один" войдет в свой критический участок. Поскольку для переменной "активный" установлено значение "истина", "процессдва" в свой Критический участок войти не может. Предположим теперь, что "процессдва" уже находится в своем критическом участке, когда "процессодин" хочет войти в критический участок. "Процессодин" устанавливает значение "истина" для переменной "первомувходитьнельзя", а затем многократно проверяет значение переменной "активный" по команде testandset. Поскольку "процессдва" находится в своем критическом участке, это значение остается истинным. Каждая команда проверки и установки обнаруживает, что "активный" имеет значение "истина", и устанавливает это значение для переменных "первомувходитьнельзя" и "активный". Таким образом, "процессодин" продолжает находиться в цикле активного ожидания, пока "процессдва" в конце концов не выйдет из своего критического участка и не установит значение "ложь" для переменной "активный". В этот момент команда проверки и установки, обнаружив это значение переменной "активный" (и установив для нее истинное значение, чтобы "процессдва" не мог больше войти в свой критический участок), установит значение "ложь" для переменной "первомувходитьнельзя", что позволит, чтобы "процессодин" вошел в свой критический участок. Этот способ реализации взаимоисключения не исключает бесконечного откладывания, однако здесь вероятность такой ситуации весьма мала, особенно если в системе имеется несколько процессоров. Когда процесс, выходя из своего критического участка, устанавливает значение "ложь" переменной "активный", команда проверки и установки testandset другого процесса, вероятнее всего, сможет "перехватить" переменную "активный" (установив для нее значение "истина") до того, как первый процесс успеет пройти цикл, чтобы снова установить значение "истина" для этой переменной.
|