Читайте также:
|
|
Рассмотрим в этом разделе так называемый кольцевой буфер (ring buffer) и покажем, каким образом он может использоваться в случаях, когда процесс-производитель должен передавать данные процессу-потребителю.
Напомним, что реализация взаимодействия в паре “производитель-
потребитель” при помощи семафоров рассматривалась нами ранее, теперь же покажем каким образом для решения этой проблемы можно воспользоваться монитором. В качестве кольцевого буфера, куда процесс-производитель помещает данные, используем массив BUFFER заданного размера N.
Поскольку размер буфера ограничен, процесс-производитель в какой-то момент может столкнуться с тем, что все элементы массива окажутся занятыми - в этом случае ему необходимо подождать, пока процесс-потребитель не прочитает и тем самым не освободит хотя бы один элемент массива.
Аналогично может возникнуть ситуация, когда процесс-потребитель хотел бы прочитать данные, а массив оказывается пустым - в этом случае процесс-потребитель должен ждать, пока процесс-производитель не поместит данные в массив.
Рассмотрим монитор Кольцевой_буфер, базовая версия которого предложена в работе 6.
Monitor Кольцевой_буфер;
var BUFFER: array [0..N-1] of Тип_данных;
Tpos: 0..N; {текущая позиция в буфере}
Zpos, Opos: 0..N-1; {соответственно, очередная заполняемая и
очередная освобождаемая позиции в буфере}
BUFNp, BUFNz: condition; { переменные-условия,
BUFNz- буфер незаполнен, является признаком, которого ждет производитель, если обнаружит, что буфер целиком заполнен, он устанавливается по сигналу потребителя о том, что тот только что освободил позицию;
BUFNp- буфер непуст, является признаком, которого ждет потребитель, если обнаружит, что буфер пуст, этот признак устанавливается по сигналу производителя о том, что он только что поместил данные в некоторую позицию буфера }
Procedure Заполнить_позицию (Данные:Тип данных);
Begin
if Tpos = N then Wait(BUFNz) {ожидание сигнала- буфер незаполнен};
BUFFER[Zpos]:= Данные;
Tpos:=Tpos+1;
Zpos:=(Zpos +1) mod N;
Signal(BUFNp) {сигнал, оповещающий, о том, что буфер непуст}
End;
Procedure Ocвободить_позицию (var Данные: Тип данных);
Begin
if Tpos=0 then Wait(BUFNp); {ожидание сигнала- буфер непуст}
Данные:= BUFFER[Opos];
Tpos:=Tpos-1;
Opos:= (Opos+1) mod N;
Signal(BUFNz) {сигнал, оповещающий о том, что буфер незаполнен}
End;
Begin
Tpos:=0;
Opos:=0;
Zpos:=0
End;
Механизам кольцевого буфера весьма удобен для реализации управления спулингом (вводом-выводом с буферизацией) в ОС. Однако следует учитывать, что кольцевой буфер должен иметь достаточно большой размер, чтобы синхронизировать скорости работы спулера (процесса-производителя данных) и деспулера (процесса-потребителя данных).
Дата добавления: 2015-01-07; просмотров: 36 | Поможем написать вашу работу | Нарушение авторских прав |