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

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

Примеры

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


Spec-Zone.ru

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