Справочник по Ada 2005
9.1 Блоки задач и объекты задач
Блок задачи объявляется с помощью объявления задачи, которое имеет соответствующий описание_тела_задачи. Объявление задачи может быть объявлением_типа_задачи, в этом случае оно объявляет именованный тип задачи; иначе, это может быть объявление_одной_задачи, в этом случае оно определяет анонимный тип задачи, а также объявляет именованный объект задачи этого типа.
Синтаксис
объявление_типа_задачи ::=
task type идентификатор_определения [часть_известного_дискриминанта] [is
[new список_интерфейсов with]
определение_задачи];
task type идентификатор_определения [часть_известного_дискриминанта] [is
[new список_интерфейсов with]
определение_задачи];
объявление_одной_задачи ::=
task идентификатор_определения [is
[new список_интерфейсов with]
определение_задачи];
task идентификатор_определения [is
[new список_интерфейсов with]
определение_задачи];
описание_тела_задачи ::=
task body идентификатор_определения is
часть_объявлений
begin
обработанная_последовательность_операторов
end [идентификатор_задачи];
task body идентификатор_определения is
часть_объявлений
begin
обработанная_последовательность_операторов
end [идентификатор_задачи];
Если идентификатор_задачи появляется в конце определения_задачи или описания_тела_задачи, он должен повторять идентификатор_определения.
Правила законности
Этот абзац был удалён.
Статическая семантика
определение_задачи определяет тип задачи и его первый подтип. Первый список элементов_задачи в определении_задачи, вместе с частью_известного_дискриминанта, если она есть, называется видимой частью блока задачи. Необязательный список элементов_задачи после зарезервированного слова private называется скрытой частью блока задачи.
Для объявления задачи без определения_задачи, предполагается определение_задачи без элементов_задачи.
Для объявления задачи со списком_интерфейсов, тип задачи наследует определяемые пользователем примитивные подпрограммы от каждого родительского типа (см. 3.9.4), так же, как и производный тип наследует определяемые пользователем примитивные подпрограммы от своих родительских типов (см. 3.4). Если первый параметр наследуемой примитивной подпрограммы имеет тип задачи или является параметром-ссылкой на тип задачи, и существует объявление_входа для одного входа с тем же идентификатором внутри объявления задачи, чей профиль соответствует профилю наследуемой подпрограммы, наследуемая подпрограмма считается реализованной соответствующим входом задачи.
Правила законности
Объявление задачи требует завершения, которое должно быть описанием_тела_задачи, и каждое описание_тела_задачи должно быть завершением некоторого объявления задачи.
Каждый интерфейс_подтип_метки из списка_интерфейсов, который появляется в объявлении задачи, должен обозначать ограниченный тип интерфейса, который не является защищённым интерфейсом.
Префиксный профиль отображения явно объявленной примитивной подпрограммы помеченного типа задачи не должен соответствовать ни одному входу типа задачи, если первый параметр подпрограммы является типом задачи или является параметром-ссылкой на тип задачи.
END_OF_DOCUMENT_MARKER Для каждого примитивного подпрограммы, унаследованного типом, объявленным в объявлении задачи, должно выполняться не более одного из следующих условий:
- унаследованная подпрограмма переопределяется примитивной подпрограммой типа задачи, в этом случае переопределяющая подпрограмма должна быть совместима по типу с унаследованной подпрограммой и не абстрактной; или
- унаследованная подпрограмма реализуется единственным входом типа задачи; в этом случае её префиксный профиль вида должен быть совместим по типу с профилем входа задачи.
Если ни одно из условий не выполняется, унаследованная подпрограмма должна быть процедурой null. В дополнение к местам, где обычно применяются правила законности (см. 12.3), эти правила также применяются в закрытой части экземпляра обобщённого модуля.
Динамическая семантика
Выполнение объявления задачи выполняет task_definition. Выполнение single_task_declaration также создаёт объект типа (безымянной) задачи.
Выполнение task_definition создаёт тип задачи и его первый подтип; оно также включает выполнение entry_declaration в заданном порядке.
В рамках инициализации объекта задачи, любые aspect_clause и любые ограничения на объект, связанные с entry_declaration соответствующего task_definition, выполняются в заданном порядке.
Выполнение task_body не оказывает никакого влияния, кроме как подтвердить, что задачи типа могут отныне активироваться без сбоя проверки выполнения.
Содержимое объекта задачи заданного типа включает:
- Значения дискриминантов объекта задачи, если таковые имеются;
- Очередь ввода-вывода для каждого входа объекта задачи;
- Представление состояния связанной задачи.
ПРИМЕЧАНИЯ
2 Помимо access_definition, имя единицы задачи в объявлении или теле единицы задачи обозначает текущий экземпляр единицы (см. 8.6), а не первый подтип соответствующего типа задачи (и, следовательно, имя не может использоваться в качестве subtype_mark).
3 Нотация selected_component может использоваться для обозначения дискриминанта задачи (см. 4.1.3). Внутри единицы задачи имя дискриминанта типа задачи обозначает соответствующий дискриминант текущего экземпляра единицы.
4 Тип задачи является ограниченным типом (см. 7.5), и поэтому исключает использование assignment_statement и предопределённых операторов равенства. Если приложению необходимо хранить и обмениваться идентификаторами задач, оно может сделать это, определив тип доступа, обозначающий соответствующие объекты задач, и используя значения доступа для целей идентификации. Присваивание доступно для такого типа доступа, как и для любого типа доступа. В качестве альтернативы, если реализация поддерживает Приложение по программированию систем, можно использовать атрибут Identity для идентификации задач (см. C.7.1).
Примеры
Примеры объявлений типов задач:
Задача тип Сервер является
вход Next_Work_Item(WI : вход Work_Item);
вход Shut_Down;
конец Сервер;
вход Next_Work_Item(WI : вход Work_Item);
вход Shut_Down;
конец Сервер;
Задача тип Keyboard_Driver(ID : Keyboard_ID := New_ID) является
новый Serial_Device с -- см. 3.9.4
вход Read (C : выход Character);
вход Write(C : вход Character);
конец Keyboard_Driver;
новый Serial_Device с -- см. 3.9.4
вход Read (C : выход Character);
вход Write(C : вход Character);
конец Keyboard_Driver;
Примеры объявлений отдельных задач:
Задача Контроллер является
вход Request(Level)(D : Item); -- семейство входов
конец Контроллер;
вход Request(Level)(D : Item); -- семейство входов
конец Контроллер;
Задача Парсер является
вход Next_Lexeme(L : вход Lexical_Element);
вход Next_Action(A : выход Parser_Action);
конец;
вход Next_Lexeme(L : вход Lexical_Element);
вход Next_Action(A : выход Parser_Action);
конец;
Задача Пользователь; -- не имеет входов
Примеры объектов задач:
Agent : Сервер;
Teletype : Keyboard_Driver(TTY_ID);
Pool : массив(1 .. 10) из Keyboard_Driver;
Teletype : Keyboard_Driver(TTY_ID);
Pool : массив(1 .. 10) из Keyboard_Driver;
Пример типа доступа, обозначающего объекты задач:
тип Клавиатура является доступ к Keyboard_Driver;
Terminal : Клавиатура := новый Keyboard_Driver(Term_ID);
Terminal : Клавиатура := новый Keyboard_Driver(Term_ID);