Справочник по Ada 2012
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 [идентификатор_задачи];
Если идентификатор_задачи появляется в конце определения_задачи или описания_тела_задачи, он должен повторять идентификатор_определения.
Параграф 8 был удалён.
Статическая семантика
Определение_задачи определяет тип задачи и его первый подтип. Первый список элементов_задачи определения_задачи, вместе с частью_известных_дискриминантов, если таковая есть, называется видимой частью блока задачи. Необязательный список элементов_задачи после ключевого слова private называется закрытой частью блока задачи.
Для объявления задачи без определения_задачи, предполагается определение_задачи без элементов_задачи.
Для объявления задачи с списком_интерфейсов, тип задачи наследует пользовательские примитивные подпрограммы от каждого типа-родителя (см. 3.9.4), так же, как производный тип наследует пользовательские примитивные подпрограммы от своих типов-родителей (см. 3.4). Если первый параметр наследуемой примитивной подпрограммы является типом задачи или параметром доступа, обозначающим тип задачи, и существует объявление_входа для одного входа с тем же идентификатором внутри объявления задачи, профиль которого соответствует типу-префиксному виду профиля наследуемой подпрограммы, то говорят, что наследуемая подпрограмма реализована соответствующим входом задачи с помощью неявно объявленной неабстрактной подпрограммы, имеющей тот же профиль, что и наследуемая подпрограмма, и которая переопределяет её.
Правила законности
Объявление задачи требует завершения, которое должно быть описание_тела_задачи, и каждое описание_тела_задачи должно быть завершением некоторого объявления задачи.
Каждый интерфейс_метка_подтипа списка_интерфейсов, появляющийся внутри объявления задачи, должен обозначать ограниченный тип интерфейса, который не является защищенным интерфейсом.
Префиксный вид профиля явно объявленной примитивной подпрограммы помеченного типа задачи не должен соответствовать типу ни одному входу типа задачи, если подпрограмма имеет то же имя определения, что и вход, и первый параметр подпрограммы является типом задачи или является параметром доступа, обозначающим тип задачи.
Для каждой примитивной подпрограммы, унаследованной типом, объявленным в объявлении задачи, может выполняться не более одного из следующего:
- Наследуемая подпрограмма переопределяется примитивной подпрограммой типа задачи, в этом случае переопределяющая подпрограмма должна соответствовать подтипу унаследованной подпрограммы и не быть абстрактной; или
- Наследуемая подпрограмма реализуется одним входом типа задачи; в этом случае её префиксный вид профиля должен соответствовать подтипу профиля входа задачи.
Если ни одно из вышеперечисленного не выполняется, наследуемая подпрограмма должна быть пустой процедурой. В дополнение к местам, где обычно применяются правила законности (см. 12.3), эти правила также применяются в закрытой части экземпляра обобщенного блока.
Динамическая семантика
Выполнение объявления задачи выполняет определение_задачи. Выполнение объявления_одной_задачи также создаёт объект заданного (безымянного) типа задачи.
Выполнение определения_задачи создаёт тип задачи и его первый подтип; оно также включает выполнение объявления_входа в заданном порядке.
В рамках инициализации объекта задачи, любые определения_аспекта и любые ограничения на объекты, связанные с объявлениями_входа соответствующего определения_задачи, выполняются в заданном порядке.
Выполнение описания_тела_задачи не имеет другого эффекта, кроме как установить, что задачи типа могут в дальнейшем активироваться без сбоя Elaboration_Check.
Выполнение описания_тела_задачи вызывается активацией задачи соответствующего типа (см. 9.2).
Содержимое объекта задачи данного типа включает:
- Значения дискриминантов объекта задачи, если таковые имеются;
- Очередь входов для каждого входа объекта задачи;
- Представление состояния связанной задачи.
ПРИМЕЧАНИЯ
2 За исключением определения_доступа, имя блока задачи внутри объявления или тела блока задачи обозначает текущий экземпляр блока (см. 8.6), а не первый подтип соответствующего типа задачи (и, следовательно, имя не может использоваться в качестве метка_подтипа).
3 Нотация выбранного_компонента может использоваться для обозначения дискриминанта задачи (см. 4.1.3). Внутри блока задачи имя дискриминанта типа задачи обозначает соответствующий дискриминант текущего экземпляра блока.
END_OF_DOCUMENT_MARKER 4 Тип задачи является ограниченным типом (см. 7.5), и поэтому исключает использование assignment_statement и предопределенных операторов равенства. Если приложению необходимо хранить и обмениваться идентификаторами задач, оно может сделать это, определив тип доступа, обозначающий соответствующие объекты задач, и используя значения доступа для целей идентификации. Присваивание доступно для такого типа доступа, как и для любого типа доступа. В качестве альтернативы, если реализация поддерживает Приложение по программированию систем, атрибут Identity может использоваться для идентификации задач (см. C.7.1).
Примеры
Примеры объявлений типов задач:
task type Server is
entry Next_Work_Item(WI : in Work_Item);
entry Shut_Down;
end Server;
entry Next_Work_Item(WI : in Work_Item);
entry Shut_Down;
end Server;
task type Keyboard_Driver(ID : Keyboard_ID := New_ID) is
new Serial_Device with -- см. 3.9.4
entry Read (C : out Character);
entry Write(C : in Character);
end Keyboard_Driver;
new Serial_Device with -- см. 3.9.4
entry Read (C : out Character);
entry Write(C : in Character);
end Keyboard_Driver;
Примеры объявлений отдельных задач:
task Controller is
entry Request(Level)(D : Item); -- семейство записей
end Controller;
entry Request(Level)(D : Item); -- семейство записей
end Controller;
task Parser is
entry Next_Lexeme(L : in Lexical_Element);
entry Next_Action(A : out Parser_Action);
end;
entry Next_Lexeme(L : in Lexical_Element);
entry Next_Action(A : out Parser_Action);
end;
task User; -- не имеет записей
Примеры объектов задач:
Agent : Server;
Teletype : Keyboard_Driver(TTY_ID);
Pool : array(1 .. 10) of Keyboard_Driver;
Teletype : Keyboard_Driver(TTY_ID);
Pool : array(1 .. 10) of Keyboard_Driver;
Пример типа доступа, обозначающего объекты задач:
type Keyboard is access Keyboard_Driver;
Terminal : Keyboard := new Keyboard_Driver(Term_ID);
Terminal : Keyboard := new Keyboard_Driver(Term_ID);