Справочник по Ada 95
9.11 Пример задач и синхронизации
Примеры
Следующий пример определяет защищенный объект буфера для сглаживания различий между скоростью вывода задачи-производителя и скоростью ввода задачи-потребителя. Например, задача-производитель может иметь следующую структуру:
task Producer;
task body Producer is
Char : Character;
begin
loop
... -- произвести следующий символ Char
Buffer.Write(Char);
exit when Char = ASCII.EOT;
end loop;
end Producer;
Char : Character;
begin
loop
... -- произвести следующий символ Char
Buffer.Write(Char);
exit when Char = ASCII.EOT;
end loop;
end Producer;
а задача-потребитель может иметь следующую структуру:
task Consumer;
task body Consumer is
Char : Character;
begin
loop
Buffer.Read(Char);
exit when Char = ASCII.EOT;
... -- обработать символ Char
end loop;
end Consumer;
Char : Character;
begin
loop
Buffer.Read(Char);
exit when Char = ASCII.EOT;
... -- обработать символ Char
end loop;
end Consumer;
Объект буфера содержит внутренний пул символов, управляемый по принципу круговой очереди. Пул имеет два индекса: In_Index, обозначающий место для следующего входного символа, и Out_Index, обозначающий место для следующего выходного символа.
protected Buffer is
entry Read (C : out Character);
entry Write(C : in Character);
private
Pool : String(1 .. 100);
Count : Natural := 0;
In_Index, Out_Index : Positive := 1;
end Buffer;
entry Read (C : out Character);
entry Write(C : in Character);
private
Pool : String(1 .. 100);
Count : Natural := 0;
In_Index, Out_Index : Positive := 1;
end Buffer;
protected body Buffer is
entry Write(C : in Character)
when Count < Pool'Length is
begin
Pool(In_Index) := C;
In_Index := (In_Index mod Pool'Length) + 1;
Count := Count + 1;
end Write;
entry Write(C : in Character)
when Count < Pool'Length is
begin
Pool(In_Index) := C;
In_Index := (In_Index mod Pool'Length) + 1;
Count := Count + 1;
end Write;
entry Read(C : out Character)
when Count > 0 is
begin
C := Pool(Out_Index);
Out_Index := (Out_Index mod Pool'Length) + 1;
Count := Count - 1;
end Read;
end Buffer;
when Count > 0 is
begin
C := Pool(Out_Index);
Out_Index := (Out_Index mod Pool'Length) + 1;
Count := Count - 1;
end Read;
end Buffer;