Ада-95. Компилятор GNAT


         

Защищенные входы и барьеры


По аналогии со входами задач, защищенный модуль может иметь защищенные входы.

Действия, выполняемые при вызове защищенного входа, предусматриваются в его теле.

Защищенные входы подобны защищенным процедурам в том, что они гарантируют взаимно исключающий доступ к данным защищенного модуля по чтению и/или записи.

Однако внутри тела защищенного модуля защищенные входы предохраняются логическим выражением, которое называют барьером, а результат вычисления этого логического выражения должен иметь предопределенный логический тип Standard.Boolean.

Если при вызове защищенного входа значение барьера есть False, то выполнение вызывающей задачи приостанавливается до тех пор, пока значение барьера не станет равным True

и внутри защищенного модуля будут отсутствовать активные задачи (задачи, которые выполняют тело какого-либо защищенного входа или какой-либо защищенной подпрограммы).

Следовательно, вызов защищенного входа может быть использован для реализации условной синхронизации.

Можно заметить, что существует строгая параллель между инструкцией принятия с охранным условием из тела задачи и телом защищенного входа с барьерным условием для защищенного модуля.

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

Хорошим примером решения упоминавшейся ранее проблемы "поставщик-потребитель" служит реализации циклического буфера с помощью защищенного типа:

-- спецификация защищенного типа protected type Bounded_Buffer is

entry Put(X: in Item); entry Get(X: out Item);

private

A: Item_Array(1 .. Max); I, J: Integer range 1 .. Max := 1; Count: Integer range 0 .. Max := 0;

end Bounded_Buffer;

-- тело защищенного типа protected body Bounded_Buffer is

entry Put(X: in Item) when Count < Max is

begin

A(I) := X; I := I mod Max + 1; Count := Count + 1; end Put;

entry Get(X: out Item) when Count > 0 is

begin

X := A(J); J := J mod Max + 1; Count := Count - 1; end Get;

end Bounded_Buffer;

<

Содержание  Назад  Вперед