9.5. ВХОДЫ, ВЫЗОВЫ ВХОДОВ И ОПЕРАТОРЫ ПРИНЯТИЯ

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

описание-входа ::=  entry идентификатор [(дискретный-диапазон)] [раздел-формальных-параметров];оператор-вызова-входа ::= имя-входа [раздел-фактических-параметров];оператор-принятия ::=   accept простое-имя-входа [(индекс-входа)]     [раздел-формальных-параметров] [do     последовательность-операторов   end [простое-имя-входа]];индекс-входа ::= выражение

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

В теле задачи каждый из ее одиночных входов или семейства входов может быть именован соответствующим простым именем. Имя входа семейства записывается в форме индексируемой компоненты: за простым именем семейства в круглых скобках следует индекс; тип этого индекса должен быть тем же, что и тип дискретного диапазона в соответствующем описании семейства входов. Вне тела задачи имя входа записывается в форме именованной компоненты, префикс которой обозначает задачный объект, а постфикс является простым именем одного из одиночных входов или семейства входов.

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

Виды параметров, определенные для параметров формального раздела описания входа, такие же, как в описании подпрограммы, и имеют тот же смысл (см. 6.2). Синтаксически оператор вызова входа подобен оператору вызова процедуры; правила сопоставления параметров остаются теми же, что и для вызовов подпрограмм (см. 6.4.1 и 6.4.2).

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

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

При предвыполнении описания входа вначале вычисляется дискретный диапазон (если он есть), затем так же, как в описании подпрограммы, предвыполняется раздел формальных параметров (если он есть).

Выполнение оператора принятия начинается с вычисления индекса входа (в случае входа семейства). Выполнение оператора вызова входа начинается с вычисления имени входа, затем следуют вычисления, требуемые для фактических параметров, как и при вызове подпрограммы (см. 6.4). Дальнейшее выполнение оператора принятия и соответствующего оператора вызова входа синхронизовано.

Если данный вход вызывается только одной задачей, то предоставляются две возможности:

• Если вызывающая задача перешла к оператору вызова входа раньше, чем имеющая этот вход задача достигла оператора принятия, то выполнение вызывающей задачи приостанавливается.

Если задача достигла оператора принятия раньше любого вызова этого входа, то выполнение задачи приостанавливается до получения такого вызова.

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

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

При попытке вызвать вход задачи, закончившей свое выполнение, в точке вызова вызывающей задачи возбуждается исключение TASKING_ERROR; это же исключение возбуждается в точке вызова, если вызванная задача заканчивает свое выполнение до принятия входа (см. также разд. 9,10 для случая, когда вызванная задача становится аварийной). Исключение CONSTRAINT_ERROR возбуждается, если индекс входа семейства не принадлежит заданному дискретному диапазону.

Примеры описаний входов:

entry READ(V : out ITEM);entry SEIZE; entry REQUEST(LEVEL)(D : ITEM); -- семейство входов

Примеры вызовов входов:

CONTROL.RELEASE;                      -— см. 9.2 и 9.1 PRODUCER_CONSUMER.WRITE(E);           -— CM. 9.1 POOL(5).READ(NEXT_CHAR);              -— CM. 9.1 и 9.2 CONTROLLER.REQUEST(LOW)(SOME_ITEM);   —- см. 9.1

Примеры операторов принятия:

accept SEIZE;accept READ(V : out ITEM) do    V := i.OCAUTEM;end READ;accept REQUEST(LOW)(D : ITEM) do   ...end REQUEST;

Примечание. Заданный в операторе принятия раздел формальных параметров не предвыполняется; он используется только для идентификации соответствующего входа.

Оператор принятия может вызывать подпрограммы, производящие вызовы входов. Оператор принятия может не содержать последовательности операторов, даже если соответствующий вход имеет параметры. Точно так же он может содержать последовательность операторов, даже если соответствующий вход не имеет параметров. Последовательность операторов в операторе принятия может включать операторы возврата. Задача может вызывать и свои собственные входы, однако это, конечно, может привести к тупиковой ситуации. Языком разрешены условные и временные вызовы входов (см. 9.7.2 и 9.7.3). Правилами языка задаче в данной момент времени разрешается находиться только в одной очереди.

Если границы дискретного диапазона семейства входов являются литералами целого типа, то индекс (в имени входа или в операторе принятия) должен быть предопределенного типа INTEGER (см. 3.6.1).

Ссылки: аварийная задача 9.10, временнбй вызов входа 9.7.3, вызов процедуры 6.4, выполнение 4.5, выражение 4.4, дискретный диапазон 3.6.1, задача 9, законченная задача 9.4, идентификатор 2.3, именуемая компонента 4.1.3, имя 4.1, индексируемая компонента 4.1.1, исключение CONSTRAINT_ERROR 11.1, исключение TASKING_ERROR 11.1, литерал перечисления 3.5.1, область 8.2, объект 3.2, оператор возврата 5-8, описание переименования 8.5, описание подпрограммы 6.1, параллельное выполнение 9, подпрограмма 6, последовательность операторов 5.1, постфикс 4.1.3, правила согласования 6.3.1, предвыполнение 3.1, 3.9, префикс 4.1, простое выражение 4.4, простое имя 4.1, процедура 6, раздел фактических параметров 6.4, совмещение 6.6, 8.7, спецификация задачи 9, тело задачи 9.1, тело подпрограммы 6.3, указывать 9.1, условный вызов входа 9.7.2, формальный раздел 6.1, целый тип 3.5.4.