![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Специальные машинные команды
В многопроцессорной конфигурации несколько процессоров разделяют доступ к общей основной памяти. В этом случае отсутствует отношение ведущий/ведомый (master/slave) — процессоры работают независимо, " на равных", и не имеется механизма прерывания, на котором могли бы основываться взаимоисключения. На уровне аппаратного обеспечения обращение к ячейке памяти исключает любые другие обращения к той же ячейке. Основываясь на этом принципе, разработчики процессоров предлагают ряд машинных команд, которые за один цикл выборки команды атомарно выполняют над ячейкой памяти два действия, такие, как чтение и запись, или чтение и проверка значения. Поскольку эти действия выполняются в одном цикле, на них не в состоянии повлиять никакие другие инструкции. Инструкция проверки и установки значения Инструкцию проверки и установки значения можно определить следующим образом: boolean testset(int i) { if (i == 0) { i = 1; return true; } else { return false; } } Инструкция проверяет значение своего аргумента i. Если его значение равно 0, функция заменяет его на 1 и возвращает true. В противном случае значение переменной не изменяется и возвращается значение false. Функция testset выполняется атомарно, т.е. ее выполнение не может быть прервано. Аппаратная поддержка взаимных исключений /* а) Инструкция проверки и установки * / const int n = /* Количество процессов */; int bolt; void P(int i) { while(true) { while(! testset(bolt)) /* Ничего не делать */; /* Критический раздел */; bolt = 0; /* Остальная часть кода */ } } void main() { bolt = 0; parbegin(Pd), P(2),..., P (n)); } /*б) Инструкция обмена */ const int n = /* Количество процессов */; int bolt; void P(int i) { int keyi; while(true) { keyi = 1; while(keyi! = 0) exchange(keyi, bolt); /* Критический раздел */; exchange(keyi, bolt); /* Остальная часть кода */ } } void main() { bolt = 0; parbegin(Pd), P (2),..., P (n)); } В листинге (а) показан протокол взаимных исключений, основанный на использовании описанной инструкции. Разделяемая переменная bolt инициализируется нулевым значением. Только процесс, который может войти в критический раздел, находит, что значение переменной bolt — 0. Все остальные процессы при попытке входа в критический раздел переходят в режим ожидания. Выйдя из критического раздела, процесс переустанавливает значение переменной bolt равным 0, после чего один и только один процесс из множества ожидающих входа в критический раздел получает требуемый ему доступ. Выбор этого процесса зависит от того, какому из процессов удалось выполнить инструкцию testset первым.
|