Spec-Zone.ru › Ada 2005
Справочник по Ada 2005

9.11 Пример задач и синхронизации

Примеры

Следующий пример определяет защищенный объект буфера для сглаживания различий в скорости вывода задачи-производителя и скорости ввода задачи-потребителя. Например, задача-производитель может иметь следующую структуру:
задача Producer;
тело задачи Producer is
Person : Person_Name; -- см. 3.10.1
begin
цикл
... -- имитировать прибытие следующего клиента
Buffer.Append_Wait(Person);
выйти если Person = null;
конец цикла;
конец Producer;
и задача-потребитель может иметь следующую структуру:
задача Consumer;
тело задачи Consumer is
Person : Person_Name;
begin
цикл
Buffer.Remove_First_Wait(Person);
выйти если Person = null;
... -- имитировать обслуживание клиента
конец цикла;
конец Consumer;
Объект буфера содержит внутренний массив имён людей, управляемый по принципу круговой очереди. Массив имеет два индекса: In_Index, обозначающий индекс для следующего имени входящего человека, и Out_Index, обозначающий индекс для следующего имени выходящего человека.
Объект Buffer определён как расширение интерфейса Synchronized_Queue (см. 3.9.4), и, как следствие, обещает реализовать абстракцию, определённую этим интерфейсом. Сделав это, Buffer может быть передан классовому методу Transfer, определённому для объектов типа, покрываемого классом Queue'Class.
защищённый Buffer is new Synchronized_Queue with -- см. 3.9.4
вход Append_Wait(Person : in Person_Name);
вход Remove_First_Wait(Person : out Person_Name);
функция Cur_Count возвращает Natural;
функция Max_Count возвращает Natural;
процедура Append(Person : in Person_Name);
процедура Remove_First(Person : out Person_Name);
приватный
Pool : Person_Name_Array(1 .. 100);
Count : Natural := 0;
In_Index, Out_Index : Positive := 1;
конец Buffer;
тело защищённого Buffer is
вход Append_Wait(Person : in Person_Name)
если Count < Pool'Length то
begin
Append(Person);
конец Append_Wait;
процедура Append(Person : in Person_Name) is
begin
если Count = Pool'Length то
вызвать исключение Queue_Error с "Buffer Full"; -- см. 11.3
конец если;
Pool(In_Index) := Person;
In_Index := (In_Index mod Pool'Length) + 1;
Count := Count + 1;
конец Append;
вход Remove_First_Wait(Person : out Person_Name)
если Count > 0 то
begin
Remove_First(Person);
конец Remove_First_Wait;
процедура Remove_First(Person : out Person_Name) is
begin
если Count = 0 то
вызвать исключение Queue_Error с "Buffer Empty"; -- см. 11.3
конец если;
Person := Pool(Out_Index);
Out_Index := (Out_Index mod Pool'Length) + 1;
Count := Count - 1;
конец Remove_First;
функция Cur_Count возвращает Natural is
begin
return Buffer.Count;
конец Cur_Count;
функция Max_Count возвращает Natural is
begin
return Pool'Length;
конец Max_Count;
конец Buffer;


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API