Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Специальные машинные команды






В многопроцессорной конфигурации несколько процессоров разделяют доступ к общей основной памяти. В этом случае отсутствует отношение ведущий/ведомый (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 первым.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.