
лекции / отчетность по СПО
.docПроектирование взаимодействующих вычислительных процессов
(взаимное исключение)
1. Блокировка памяти – запрет одновременного исполнения двух (и более) команд, обращающихся к одной и той же ячейке памяти, но допускается чередование доступа.
Например:
Пусть имеется два циклического процесса, каждый из которых состоит из критического интервала CS1 и CS2 и оставшейся части кода процесса PR1 и PR2.
Взаимное исключение достигается за счет того, что процессы PR1 и PR2 входили в свои критические интервалы попеременно.
Для этого вводится переключатель Р, указывающий на то, чья очередь войти в критическую секцию.
Var P: integer;
begin
P: =1; {P=1 в CS наход.процесс PR1}
begin
while true do
begin
while P=2 do begin end;
CS1; {кр.секции (CS) процесса PR1}
P:=2;
PR1`;
end;
and
while true do
begin
while P=1 do begin end;
CS2;
P:=1;
PR2
end
end
end.
Листы программы, в которых происходит обращение к критическим ресурсам над критическими секциями (интервалами) CS.
Критический ресурс – ресурс, не допускающий одновременного использования несколькими процессами.
2. Алгоритм Деккера
label 1,2; {P1, P2 – переключение 1,2 ; D - очередь}
var P1,P2: boolean;
D:integer;
begin P1:= false; P2:= false
D :=1;
begin
while true do
begin P1:= true;
1: if P2= true&Ren
if D =1&Ren go to 1
else begin P1:= false;
while D =2 do begin end;
end
else begin
CS1
D:=2; P1:= false
end
end
end
and
while true do
begin P2:=1;
2: if P1= true &Ren
if D =2 then go to 2
else begin P2: false;
while D =1 do begin end
end
else begin
CS2
D :=1; P2:= false
end
end
end
end.
Если P2= true и P1= false , то выполняется CS2 независимо от значений 0, и наоборот, если P2= true и P1= true , то выполняется CS того процесса, на который указывало значение 0.
Синхронизация посредством операции
«проверка и установка»
TS
Вводится переменная common - общая для всех процессов.
Common=1, если какой-либо из процессов находится в своем CS. С каждым процессом связана переменная local1, local2, принимающая значение common при операции TS
и common установившееся в 1 (BTS) в Ассемблере.
Var common, local2, local1: integer;
begin
common:=0
begin
PR1: while true do
begin
local1:=1;
while local1=1 do TS ( local1, common)
CS1;
common:=0;
PR1;
end
and
PR2: while true do
begin
local2:=1;
while local2=1 do TS (local2, common)
CS2;
common:=0;
PR2;
end
end
end.
Пусть должен войти в CS PR1. При этом local1=1.
После TS (local1, common), local1=0, при этом common=1.
PR1 перейдет в CS. После выполнения CS1 common=0, что даст возможность PR2 войти в CS2.
Семафоры
Термин «семафор» введен Даркстройем.
Семафор – переменная специального типа, которая доступна параллельным процессам для проверки над ней только 2-х операций:
- «закрытия» P;
- «открытия» V;
Семафор выполняет роль критического ресурса.
Схема работы семафора:
Сначала исследуется состояние критического ресурса, идентифицируемое значение семафора, а затем осуществляется доступ к критическому ресурсу или отказ от него на время.
При отказе доступа к критическому ресурсу исполняется режим «пассивного ожидания» и является примитивами относительно семафора.
Смысл P(S) заключен в проверке текущего значения семафора, и если S<0 , то осуществляется переход к следующей за примитивом операции. В противоположном случае процесс находится в состоянии «пассивного ожидании».
V(S) связана с увеличением значения семафора на единицу перевода одного или нескольких процессов в состоянии готовности к центральному процессору.
initSem - инициализация семафора
initSem (имя семафора, начальное значение семафора)
var S: semafor;
begin initsem (S,1);
begin
PR1: while true do
begin P(S);
CS1
V(S)
end
and
PR2: while true do
begin P(S);
CS2
V(S)
end
end
end.
Семафор S имеет начальное значение равное P. Если PR1 и PR2 попытаются одновременно выполнить P(S), то это удастся успешно сделать только одному из них. Пусть это сделал PR2, тогда он закрывает семафор S, после чего выполняется CS2. PR1 в рассмотренном состоянии будет заблокирован на семафоре S. После выполняется V(S) процессором PR2семафор открывается, указывая на возможность захвата каким-либо процесса освободившегося критического ресурса. При этом производится перевод PR1 из заблокированного состояния в состояние готовности.
Мьютиксы – простейшие двоичные семафоры, которые могут находиться в одном из двух состояний – отличном или неотличном (открытом или закрытом).
Когда какая-либо задача, принадлежащая какому-либо процессу, становится объекта mutex, то mutex переводится в неотличное состояние. Если задача освобождает мьютекс, то его состояние становится отличным.
Createmutex - создать
Openmutex - открыть
WaitForSingleObject - ожидание
Releasemutex - освобождение
Мониторы Хоара
Так как семафоры слишком примитивны, т.е. не указывают на синхронизирующее устройство, с которым он связан, или на критический ресурс. Алгоритмы становятся сложными, ненаглядными.
Поэтому разработали мониторы Хоара.
Монитор – пассивный набор разделяемых переменных и повторно входимых процедур доступа к ним, которым процессы пользуются в режиме разделения, причем в каждый момент им может пользоваться только один процесс.
Процесс, желающий получить доступ к разделяемым переменным, должен обратиться к монитору, который либо предоставит доступ, либо
Откажет в нем. Если ресурс занят, то процедура монитора выдает команду ожидание WAIT с указанием условия ожидания.
Если со временем процессы ожидают освобождение данного ресурса, то монитор выполняет команду извещение SIGNAL, чтобы один из ожидающих процессов мог получить данный ресурс и покинуть монитор.
Пример монитора Хоара:
monitor resourse;
conolition free; { условие свбодный}
var busy: Boolean { busy - занят}
procedure REQUEST;
begin
if busy then WAIT (free);
busy:=true;
take off; {выдать ресурс}
end;
procedure RELEASE;
begin
take on;
busy:=false;
SIGNAL (free)
end;
begin
busy:=false;
end.
Ресурс динамически запрашивается и освобождается процессами, которые обращаются к процессу REQUEST и RELEASE. Если PR обращается к REQUEST в тот момент, когда ресурс используется, busy:=true и REQUEST выполняет операцию монитора WAIT (free). Эта операция блокирует процесс, обратившихся к процедуре REQUEST. Процесс помещается в конец очереди процессов, ожидающих, пока не будет выполнено условие free.
Когда PR, использует ресурс и обращается к RELEASE, операция монитора SIGNAL деблокирует процесс, находящийся в начале очереди, не позволяя, исполнятся никакой другой процедуре внутри того же монитора. Если SIGNAL выполняется в то время, когда нет процесса, ожидаемого условия вне, то никакие действия не выполняются.
Почтовые ящики
Для хранения посланного, но ещё не полученного сообщения необходимо место – буфер сообщений (почтовый ящик).
Для того чтобы послать процессору Р2 какое-то сообщение, процессР1 просто помещает это сообщение в почтовый ящик, откуда процесс Р2 может его в любое время взять.
Почтовый ящик состоит из головного элемента, в котором находится информация в данном почтовом ящике, и из нескольких буферов, в которые помещают сообщения.
Двунаправленные почтовые ящики, позволяют подтверждать прием сообщений.
Реализация – с помощью примитивных операторов P и V, или с помощью процедур:
- SEND_MESSAGE (получать, сообщение, буфер)- переписать сообщение;
- WAIT_MESSAGE (отправитель, сообщение, буфер) – блокировать процесс и т.д., пока в очереди не появится сообщение и т.д.
Конвейеры
Это средство с помощью которого можно производить обмен данными между процессами.
Размер не более 64 Кбайт, работает циклически.
Представляет собой буферную память, работающую по принципу
Чтобы начать работу с конвейером, процесс сначала должен заказать его у ОС и получить в свое распоряжение. Процессы, знающие идентификатор конвейера, могут через него обмениваться данными.
Очереди сообщений – аналогично конвейерам, но работают в одном направлении.
Используют дисциплины:
- FIFO – прев.-перв.
- LIFO – посл.-перв.
- приоритетный доступ
- произвольный доступ
Отличаются от конвейера:
- при чтении не удаляются из канала
- присутствие адреса в памяти и их размер, а не сами сообщения.
Тупики:
Ресурсы:
- RR или SR – повторное использование
- CR – потребляемые ресурсы
Модель Холта:
R1
R2
Пусть Р1 запрещает две единицы R1 и одну единицу R2.
Пусть R2 принимает две единицы R1 и ему нужна одна единица R2.
Если процесс должен получить все запрашиваемые им ресурсы, прежде чем освободить хотя бы один из них, то удовлетворение запросы P1 приведет к тупиковой ситуации: P1 не сможет продолжатся до тех пор, пока P2 не освободит единицу ресурса R1, а процесс З2 не сможет продолжаться до тех пор, пока P1 не освободит единицу R2. Причина – неупорядоченные попытки процессов войти в критические интервалы.