Иллюстрированный самоучитель по теории операционных систем

Примитивы взаимоисключения

В классической работе Г. М. Дейтела [Дейтел 1987] предлагается несколько последовательных усовершенствований механизма взаимоисключений, основанного на флаговых переменных, и как завершающий этап этого анализа приводится алгоритм взаимоисключений Деккера (пример 7.2).

Пример 7.2. Алгоритм Деккера (цит. по [Дейтел 1987])

program АлгоритмДеккера;
var
избранный процесс: (первый, второй);
п1 хочет войти, п2 хочет войти: Boolean; procedure процесс один;
begin
while true do begin
п1 хочет войти: = True;
while п2 хочет войти do
if избранный процесс = второй then
begin
п1 хочет войти: = False;
while избранный процесс = второй do;
п1 хочет войти: = True;
end
критический участок 1;
избранный процесс: = второй;
п1 хочет войти: = False;
…
end
end
procedure процесс два;
begin
while true do
begin
п2 хочет войти: = True;
while п1 хочет войти do
if избранный процесс = первый then
begin
п2 хочет войти: = False;
while избранный процесс = первый do;
п2 хочет войти: = True;
end
критический участок 2;
избранный процесс: = первый;
п2 хочет войти: = False;
…
end
end D
begin
п1 хочет войти: = False;
п2 хочет войти: = False;
избранный процесс: = первый;
parbegin процессодин;
процесс два;
parend
end.

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

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.