Spec-Zone.ru › Ada 2022
Руководство по Ada (Ada 2022)

9.7.1 Выбор приема

Этот вид оператора select_statement позволяет сочетать ожидание и выбор из одного или нескольких вариантов. Выбор может зависеть от условий, связанных с каждым вариантом оператора selective_accept.

Синтаксис

selective_accept ::=
select
[guard]
select_alternative
{ or
[guard]
select_alternative }
[ else
последовательность_операторов ]
end select;
guard ::= when condition =>
select_alternative ::=
accept_alternative
| delay_alternative
| terminate_alternative
accept_alternative ::=
accept_statement [последовательность_операторов]
delay_alternative ::=
delay_statement [последовательность_операторов]
terminate_alternative ::= terminate;
Оператор selective_accept должен содержать по крайней мере один accept_alternative. Кроме того, он может содержать:
оператор terminate_alternative (только один); или
один или несколько операторов delay_alternative; или
часть else (зарезервированное слово else, за которым следует последовательность_операторов).
Эти три возможности взаимоисключающие.

Правила легальности

Если оператор selective_accept содержит более одного delay_alternative, то все они должны быть delay_relative_statements, или все должны быть delay_until_statements для одного и того же типа времени.

Динамические семантики

Вариант select_alternative называется открытым, если он не предшествует оператору guard, или если выражение condition его оператора guard равно True. В противном случае он называется закрытым.
При выполнении оператора selective_accept вычисляются все условия condition оператора guard; определяются открытые варианты. Для открытого delay_alternative также вычисляется выражение delay_expression. Аналогично, для открытого accept_alternative для входа в семейство также вычисляется entry_index. Эти вычисления выполняются в произвольном порядке, за исключением того, что выражение delay_expression или entry_index не вычисляются до тех пор, пока не будет вычислено соответствующее условие condition, если таковое имеется. Затем выбор и выполнение одного открытого варианта или части else завершают выполнение оператора selective_accept; правила этого выбора описаны ниже.
Открытые accept_alternative рассматриваются в первую очередь. Выбор одного такого варианта происходит немедленно, если соответствующий вход уже имеет очереди вызовов. Если несколько вариантов могут быть выбраны таким образом, один из них выбирается в соответствии с политикой очереди ввода-вывода (см. 9.5.3 и D.4). При выборе такого варианта выбранный вызов удаляется из очереди входа, и выполняется соответствующая handled_sequence_of_statements (если она есть) соответствующего оператора accept_statement; после завершения взаимодействия выполняются последующие последовательность_операторов варианта. Если немедленный выбор невозможен (в вышеупомянутом смысле) и нет части else, задача блокируется до тех пор, пока не будет выбран открытый вариант.
Выбор других форм вариантов или части else выполняется следующим образом:
  • Открытый delay_alternative выбирается, когда достигает время его истечения, если до момента истечения времени невозможно выбрать accept_alternative или другой delay_alternative. Если несколько delay_alternative имеют это же время истечения, один из них выбирается в соответствии с политикой очереди (см. D.4); по умолчанию политика очереди произвольно выбирает среди delay_alternatives, время истечения которых прошло.
  • Часть else выбирается и её последовательность_операторов выполняется, если не может быть немедленно выбран accept_alternative; в частности, если все варианты закрыты.
  • Открытый terminate_alternative выбирается, если выполнены условия, указанные в конце 9.3.
Исключение Program_Error возникает, если все варианты закрыты, и нет части else.
ПРИМЕЧАНИЕ Оператор selective_accept может иметь несколько открытых delay_alternatives. Оператор selective_accept может иметь несколько открытых accept_alternatives для одного входа.

Примеры

Пример тела задачи с выбором приема:
task body Server is
Current_Work_Item : Work_Item;
begin
loop
select
accept Next_Work_Item(WI : in Work_Item) do
Current_Work_Item := WI;
end;
Process_Work_Item(Current_Work_Item);
or
accept Shut_Down;
exit; -- Запрошен досрочный выход
or
terminate; -- Нормальный выход в конце области видимости
end select;
end loop;
end Server;


Spec-Zone.ru

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