9.7. ОПЕРАТОРЫ ОТБОРА

Существует три формы операторов отбора. Одна форма обеспечивает отбор с ожиданием одной или нескольких альтернатив. Две другие обеспечивают условный и временной вызовы входа.

оператор-отбора ::= отбор-с-ожиданием    | условный-вызов-входа | временной-вызов-входа

Ссылки: временной вызов входа 9.7.3, отбор с ожиданием 9.7.1, условный вызов входа 9.7.2.

9.7.1. ОТБОР С ОЖИДАНИЕМ

Эта форма оператора отбора допускает объединение ожидания и отбор с ожиданием одной или нескольких альтернатив. Отбор может зависеть от условий, связанных с каждой альтернативой отбора с ожиданием.

отбор-с-ожиданием ::=    select       альтернатива-отбора    {or       альтернатива-отбора)    [else       последовательность-операторов]    end select;альтернатива-отбора ::=    [when условие = >]      альтернатива-отбора-с-ожиданиемальтернатива-отбора-с-ожиданием ::= альтернатива-принятия   | альтернатива-задержки | альтернатива-завершенияальтернатива-принятия ::=   оператор-принятия [последовательность-операторов]альтернатива-задержки ::=   оператор-задержки [последовательность - операторов]альтернатива-завершения ::= terminate;

Оператор отбора с ожиданием должен содержать по крайней мере одну альтернативу принятия. В дополнение к этому оператор отбора с ожиданием может содержать либо альтернативу завершения (только одну), либо одну или несколько альтернатив задержки, либо раздел else; эти три возможности являются взаимоисключающими.

Альтернатива отбора называется открытой, если она, не начинается с зарезервированного слова when или если значение условия — TRUE. В противном случае альтернатива называется закрытой.

При выполнении оператора отбора с ожиданием в произвольном, не определенном в языке порядке вычисляются все условия, заданные после зарезервированного слова when; определяются открытые альтернативы. Для открытой альтернативы задержки вычисляется выражение длительности задержки. Для открытой альтернативы принятия входа семейства вычисляется индекс входа. Выполнение отбора с ожиданием заканчивается отбором и вычислением либо одной из открытых альтернатив, либо раздела else; правила такого отбора описываются ниже.

Первыми рассматриваются открытые альтернативы. Отбор одной из таких альтернатив производится немедленно, если возможно соответствующее рандеву, т.е. если другая задача произвела вызов соответствующего входа и ожидает его принятия. Если таким образом могут быть отобраны несколько альтернатив, то одна из них выбирается произвольно (которая именно, в языке не определено). После отбора такой альтернативы выполняются соответствующий оператор принятия и следующая за ним последовательность операторов (если она есть). Если никакое рандеву не может произойти немедленно и отсутствует раздел else, то задача ждет, пока можно будет выбрать открытую альтернативу отбора с ожиданием.

Отбор других форм альтернатив или раздела else осуществляется следующим образом.

' Отбирается открытая альтернатива задержки, если никакая другая альтернатива принятия не может быть выбрана до истечения указанной задержки ожидания (немедленно, если длительность отрицательная или нулевая и при отсутствии очереди вызовов входа); затем выполняются возможные последующие операторы этой альтернативы. Если возможен отбор нескольких альтернатив задержки (т.е. если задержки у них одинаковы), то одна из них выбирается произвольно.

• Отбирается раздел else и выполняется последовательность операторов этого раздела, если нельзя немедленно отобрать альтернативу принятия, в частности если все альтернативы закрыты.

•Отбирается открытая альтернатива завершения, если перечисленные в разд. 9.4 условия удовлетворены. Из других правил следует, что нельзя отобрать альтернативу завершения, пока существует очередь вызовов 'любого входа задачи.

Исключение PROGRAM_ERROR возбуждается, если все альтернативы закрыты и раздел else отсутствует.

Пример оператора отбора:

select   accept DRIVER_AWAKE_SIGNAL;or   delay 30.0*SECONDS;   STOP_THE_TRAIN;end select;

Пример тела задачи с оператором отбора:

task body RESOURCE is   BUSY : BOOLEAN := FALSE;begin    loop     select        when not BUSY=>           accept SEIZE do               BUSY := TRUE;           end:     or        accept RELEASE do            BUSY := FALSE;        end;     or        terminate;     end select;   end loop;end RESOURCE;

Примечание. В отборе с ожиданием допускаются несколько открытых альтернатив задержки или несколько открытых альтернатив принятия одного и того же входа.

Ссылки: вход 9.5, вызов входа 9.5, выражение задержки 9.6, длительность 9.6, задача 9, индекс входа 9.5, исключение PROGRAM_ERROR 11.1, оператор задержки 9.6, оператор отбора 9.7, оператор принятия 9.5, описание 3.1, очередь вызовов входа 9.5, последовательность операторов 5.1, рандеву 9.5, условие 5.3.