Монитор Хоара

Содержание

Слайд 2

10. Монитор Хоара 2015 v.01 Процедура доступа monitor Буфер; var СамБуфер:

10. Монитор Хоара 2015 v.01

Процедура доступа

monitor Буфер;
var СамБуфер:
array[1..ДлинаБуфера] of Данное;
var

СчетчикЗаписей: integer;
procedure Записать(d: Данное);
begin
...
end;
function Прочитать(): Данное;
begin
...
end;
begin
СчетчикЗаписей:= 0;
end Буфер.

Поставщик:
loop
D:= Производство();
Буфер.Записать(D);
endloop.

Потребитель:
loop
D:= Буфер.Прочитать();
Обработка(D);
endloop.

Слайд 3

10. Монитор Хоара 2015 v.01 Механизм сигналов Желательна возможность «нотификации» изменений

10. Монитор Хоара 2015 v.01

Механизм сигналов

Желательна возможность «нотификации» изменений состояния ресурсов

монитора. Пример: «Поставщик потребитель» - требуется оценивать состояние буфера (полон/пуст).
Решение 1 Плохое.
Задача «берет на себя»
функции диспетчера и
сама «стучится» в
монитор, занимая ресурс

Монитор
function БуферПолон: boolean;
if(СчетчикЗаписей < ДлинаБуфера)
return false;
else
return true;
function БуферПуст: boolean;
if(СчетчикЗаписей > 0)
return false;
else
return true;

Поставщик

While(БуферПолон)

Потребитель

While(БуферПуст)

Слайд 4

10. Монитор Хоара 2015 v.01 Решение 2 (совсем плохое) Процесс «анализирует»

10. Монитор Хоара 2015 v.01

Решение 2 (совсем плохое)
Процесс «анализирует» возможность

доступа и «засыпает» на некоторое
время (ОС предоставляет возможность «заснуть» на время
t - sleep(t), с передачей управления):
while(Условие){
sleep(t);
}
a - Увеличивается latency
b - Можно «потерять» момент освобождения монитора

t

Latency (a)

Разрешение доступа

Запрос от другого процесса (b)

Слайд 5

10. Монитор Хоара 2015 v.01 Сигналы - определение Операции над сигналами:

10. Монитор Хоара 2015 v.01

Сигналы - определение

Операции над сигналами:

Сигнал S =

new Сигнал(); (Здесь строится очередь задач, ждущих получения сигнала S)
wait(S):
поставить активный процесс в очередь, связанную с сигналом S
notify(S):
первый процесс из очереди S ставится в «очередь готовых»;
check(S):Integer:
возвращает кол-во процессов, ждущих в очереди S

Тип данных: type Сигнал

Слайд 6

10. Монитор Хоара 2015 v.01 var Полон, Пуст: Сигнал; procedure Записать(d:

10. Монитор Хоара 2015 v.01
var Полон, Пуст: Сигнал;
procedure Записать(d: Данное);
begin

if(СчетчикЗаписей => ДлинаБуфера) then
wait(Полон)
endif
ЗаписатьДанноеВБуфер(d);
СчетчикЗаписей:= СчетчикЗаписей + 1;
notify (Пуст)
end;
function Прочитать(): Данное
begin
if(СчетчикЗаписей = 0) then
wait(Пуст)
endif
Прочитать:= ЧтениеЗаписиИзБуфера();
СчетчикЗаписей:= СчетчикЗаписей - 1;
notify (Полон)
end;

Пример – ресурсы монитора «Буфер»

Слайд 7

10. Монитор Хоара 2015 v.01 Еще одна «тонкость» ... if(СчетчикЗаписей ==

10. Монитор Хоара 2015 v.01

Еще одна «тонкость» ...
if(СчетчикЗаписей == 0) then

wait(Пуст)
endif
Но до выполнения wait(Пуст) условие СчетчикЗаписей == 0 может поменяться несколько раз («На время выполнения процессов не накладывается ниткаких ограничений»)
while(СчетчикЗаписей == 0) do
wait(Пуст)
endwhile

Так что многое, представленное ранее – не совсем корректно

Слайд 8

10. Монитор Хоара 2015 v.01 class Buffer { int[] buf; public

10. Монитор Хоара 2015 v.01

class Buffer {
int[] buf;
public synchronized void put

(int s) {
if (counter < CAPACITY) {
counter ++; write_to_buf;
this.notify();
} else {
this.wait();
};
};
public synchronized int get () {
if (counter > 0) {
counter--; read_from_buf;
this.notify();
} else {
this.wait();
};
return buf[counter];
}
}

Монитор в Java

Слайд 9

10. Монитор Хоара 2015 v.01 Пример - задача «Читатели-Писатели» Информационный фонд

10. Монитор Хоара 2015 v.01

Пример - задача «Читатели-Писатели»

Информационный
фонд

П1

П2

ПN

Ч1

Ч2

ЧM

M Читателей и N

Писателей получают доступ к Информационному Фонду
Реализовать механизм, позволяющий обеспечить следующее условие:
в каждый момент времени могут работать
не более одного Писателя или не более M
Читателей
Слайд 10

10. Монитор Хоара 2015 v.01 Схема реализации monitor ЧП; var МожноЧитать,

10. Монитор Хоара 2015 v.01

Схема реализации

monitor ЧП;
var МожноЧитать,
МожноПисать: Сигнал;
КтоТоПишет:

boolean;
Читатели: 0..M;
procedure НачалоЧтения;
procedure КонецЧтения;
procedure НачалоЗаписи;
procedure КонецЗаписи;
begin
КтоТоПишет:= false;
Читатели:= 0;
end ЧП.

Читатель:
loop
ЧП.НачалоЧтения();
РаботаСФондомЧ();
ЧП.КонецЧтения();
РазноеЧ;
endloop.

Писатель:
loop
ЧП.НачалоЗаписи();
РаботаСФондомП();
ЧП.КонецЗаписи();
РазноеП;
endloop.

Слайд 11

10. Монитор Хоара 2015 v.01 Начало и окончание чтения procedure НачалоЧтения();

10. Монитор Хоара 2015 v.01

Начало и окончание чтения
procedure НачалоЧтения();
begin
while

(КтоТоПишет)or(check(МожноПисать)>0)
wait(МожноЧитать);
Читатели:= Читатели + 1;
notify (МожноЧитать)
end;
procedure КонецЧтения();
begin
Читатели:= Читатели - 1;
if(Читатели = 0) then
notify (МожноПисать)
endif
end;
Слайд 12

10. Монитор Хоара 2015 v.01 Начало и окончание записи procedure НачалоЗаписи();

10. Монитор Хоара 2015 v.01

Начало и окончание записи
procedure НачалоЗаписи();
begin
while(Читатели

> 0)or(КтоТоПишет)
wait(МожноПисать);
КтоТоПишет:= true;
end;
procedure КонецЗаписи();
begin
КтоТоПишет:= false;
if(check(МожноЧитать) > 0) then
notify(МожноЧитать)
else
notify (МожноПисать)
endif;
end;