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

Примечание. Если все вложенные операторы блока программы поименованы, то имя каждого программного модуля, вложенного в блок, всегда может быть записано как расширенное имя, начинающееся с идентификатора STANDARD (в случае, когда этот пакет не является скрытым) .

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

  1. Контекст разрешения совмещения

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

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

В таком месте рассматриваются все видимые описания. Вхождение пра­вильно только тогда, когда есть точно одна интерпретация для каждого эле­мента самого вложенного полного контекста. Полный контекст — это:

  • описание;

  • оператор;

  • спецификатор представления.

При рассмотрении возможных интерпретаций полного контекста учиты­ваются только те правила, которые касаются синтаксиса, области действия и видимости, а также те, которые даны ниже. Учитываются:

  1. любое правило, которое требует, чтобы имя или выражение имели определенный тип или такой же тип, как другое имя или выражение;

  2. любое правило, которое требует, чтобы тип имени или выражения был типом определенного класса; аналогично, любое правило, которое тре­бует, чтобы определенный тип был дискретным, целым, вещественным, универсальным, символьным, логическим или нелимитируемым типом;

  3. любое правило, которое требует, чтобы префикс соответствовал оп­ределенному типу;

  4. любое правило, которое задает определенный тип в качестве типа ре­зультата базовой операции, и любое правило, которое устанавливает, что это тип определенного класса;

  5. правила, которые требуют, чтобы тип агрегата или строкового лите­рала был определен исключительно охватывающим полным контекстом (см. разд. 4.3 и 4.2). Аналогично, правила, которые требуют, чтобы тип префикса атрибута, тип выражения оператора выбора или тип операнда пре­образования типа были определены независимо от контекста (см. разд. 4.1.4, 5.4,4.6 и 6.4.1);

  6. правила, данные в разд. 6.6 по разрешению вызовов совмещенных подпрограмм, в разд. 4.6 по неявным преобразованиям универсальных вы­ражений, в разд. 3.6.1 по интерпретации дискретных диапазонов с граница­ми, имеющими универсальный тип, в разд. 4.1.3 по интерпретации расширен­ного имени, чей префикс обозначает подпрограмму или оператор принятия.

Для имен подпрограмм, используемых в качестве аргументов прагмы, следуют ^другому правилу: прагма может применяться для нескольких сов­мещенных подпрограмм, как пояснено в разд, 6.3,2 для прагмы INLINE, в разд. 11.7 для прагмы SUPPRESS и в разд. 13.9 для прагмы INTERFACE.

Аналогично этому, данные в спецификаторах контекста (см. разд. 10.1.1) и спецификаторах адреса простые имена следуют другим правилам.

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

Аналогично, при разрешении совмещения не учитываются подтипы. (Нарушение ограничения не делает программу неправильной, но возбуждает исключение во время выполнения программы).

Спецификация параметра цикла есть описание и, следовательно, полный контекст.

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

9. ЗАДАЧИ

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

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

Некоторые задачи могут иметь входы. Вход задачи может быть вызван другими задачами. Задача принимает вызов одного из своих входов выпол­нением оператора принятия этого входа. Синхронизация достигается по­средством рандеву между задачей, вызывающей вход, и задачей, принимаю­щей вызов. Некоторые входы имеют параметры; вызовы входов и операто­ры принятия таких входов являются основным средством обмена значения­ми между задачами.

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

Примечание. Параллельные задачи (параллельные логические процессоры) могут быть реализованы на многомашинных комплексах, многопроцессорных ЭВМ или че­редующимся выполнением на одном физическом процессоре. С другой стороны, если реализация способна определить, что тот же результат получается при параллельном выполнении частей одной задачи на различных физических процессорах, то можно при­нять и такой способ выполнения; в этом случае несколько физических процессоров реализуют один логический процессор.

  1. Спецификации задач и тела задач

Заданный модуль состоит из спецификации задачи и тела задали. Специ­фикация задачи, которая начинается зарезервированными словами task type, описывает задачный тип. Значение объекта задачного типа указывает зада­чу. Если задача имеет входы, то они описываются в спецификации задачи; эти входы также называются входами объекта. Выполнение задачи опреде­ляется соответствующим телом задачи.

Спецификация задачи без зарезервированного слова type определяет одиночную задачу. Описание такой задачи эквивалентно описанию аноним­ного задачного типа одновременно с описанием объекта этого задачного ти­па, а идентификатор задачного модуля именует объект. В остальной части данной главы пояснения даются в терминах описаний задачного типа; со­ответствующие пояснения для одной задачи следуют из упомянутого отно­шения эквивалентности.

описание_задачи : : = спецификация_задачи;

спецификация_задачи : : =

task [type] идентификатор [is

{ описание_входа>

{спецификатор_представления}

end [простое_имя_зад«чм] ];

тело_задачи : : =

task body простое_имя_задачы is

[раздел_описаний]

begin

последовательность_операторов

[exception

обработчик_исключения

<обработчик_исключения}]

end [простое_имя_задчи];

Простое имя в начале тела задачи должно совпадать с идентификатором задачного модуля. Аналогично, если в конце спецификации или тела задачи появляется простое имя, то оно должно совпадать с идентификатором за­дачного модуля. Внутри тела задачи имя соответствующего задачного моду­ля может также быть использовано для ссылки на объект-задачу (указы­вать на задачу), тело которой выполняется в данный момент; кроме того, не допускается использование этого имени типа или производного от него типа или подтипа в качестве обозначения типа внутри собственно задачного модуля.

При предвыполнении спецификации задачи описания входов и специфи­каторы представления (если они есть) предвыполняются в том порядке, в котором они даны. Спецификаторы представления применяются только ко входам, описанным в спецификации задачи (см. 13.5).

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

Выполнение тела задачи вызывается активизацией задачного объекта соответствующего типа (см. 9.3). Возможные в конце тела задачи обработ­чики исключений обрабатывают исключения, возбуждаемые в ходе выпол­нения последовательности операторов тела задачи (см. 11.4).

Примеры спецификации заданных типов:

task type РЕСУРС is

entry ЗАХВАТИТЬ;

entry ОСВОБОДИТЬ;

end РЕСУРС;

task type ДРАЙВЕР_КЛАВИАТУРЫ is

entry ЧИТАТЬ (C: out CHARACTER);

entry ПИСАТЬ (C: in CHARACTER);

end ДРАЙВЕР_КЛАВИАТУРЫ;

Примеры спецификации одной задачи:

task ПОСТАВЩИК ПОТРЕБИТЕЛЬ is

entry ЧИТАТЬ (V: out ЭЛЕМЕНТ) ;

entry ПИСАТЬ (Е: in ЭЛЕМЕНТ);

end;

task КОНТРОЛЛЕР is

entry ЗАПРОСИТЬ (УРОВЕНЬ) (D: ЭЛЕМЕНТ); --семейство входов

end КОНТРОЛЛЕР;

task ПОЛЬЗОВАТЕЛЬ; - - не имеет входов

Пример спецификации задачи и соответствующего тела:

task ЗАЩИЩЕННЫЙ_МАССИВ is

- - ИНДЕКС и ЭЛЕМЕНТ - это глобальные типы entry ЧИТАТЬ (К: in ИНДЕКС; V: out ЭЛЕМЕНТ) ; entry ПИСАТЬ (К: in ИНДЕКС; Е; in ЭЛЕМЕНТ);

end;

task body ЗАЩИЩЕННЫЙ_МАССИВ is

ТАБЛИЦА: array (ИНДЕКС) of ЭЛЕМЕНТ: = (ИНДЕКС => НУЛЬ _Э ЛЕМЕНТ); begin

loop

select

accept ЧИТАТЬ (К: in ИНДЕКС; V: out ЭЛЕМЕНТ) do

V: = ТАБЛИЦА (К);

end ЧИТАТЬ;

or

accept ПИСАТЬ (К: in ИНДЕКС; Е: in ЭЛЕМЕНТ) do ТАБЛИЦА (К): = Е;

end ПИСАТЬ;

end select;

end loop;

end ЗАЩИЩЕННЫЙ-МАССИВ;

Примечание. Спецификация задачи задает интерфейс задачам данного типа с дру­гими задачами тех же или различных типов, а также с главной программой.

  1. Заданные типы и заданные объекты

Заданный тип является лимитируемым типом (см. 7.4.4). Следователь­но, для объектов заданного типа не определены ни присваивание, ни предоп­ределенное сравнение на равенство и неравенство; более того, вид out не допустим для формального параметра заданного типа.

Задачный объект — это объект заданного типа. Значение заданного объек­та указывает задачу со входами соответствующего задачного типа, а ее вы­полнение определено соответствующим телом задачи. Если заданный объект является объектом или подкомпонентом объекта, заданными описанием объекта, то его значение определяется предвыполнением описания объекта. Если заданный объект является объектом или подкомпонентом объекта, созданными при выполнении генератора, то его значение определяется вы­полнением генератора. Для всех видов параметров, если фактический пара­метр указыавет задачу, сопоставляемый формальный параметр указывает ту же задачу; это же относится к подкомпоненту фактического параметра и к соответствующему подкомпоненту сопоставляемого формального пара­метра; наконец, то же справедливо и для параметров настройки.

Примеры:

УПРАВЛЕНИЕ: РЕСУРС;

ТЕЛЕТАЙП: ДРАЙВЕР_КЛАВИАТУРЫ;

ПУЛ: array (1. .10) of ДРАЙВЕР_КЛАВИАТУРЫ;

- - см. также примеры описаний одиночных задач в 9.1

Пример ссылочного типа, указывающего заданный объект:

type КЛАВИАТУРА is access ДРАЙВЕР_КЛАВНАТУРЫ;

ТЕРМИНАЛ: КЛАВИАТУРА: = new ДРАЙВЕР_КЛАВИАТУРЫ;

Примечание. Поскольку задачный тип является лимитируемым, он может появить­ся как определение лимитируемого личного типа в личном разделе и как фактический параметр настройки, сопоставляемый формальному параметру лимитируемого типа. С другой стороны, тип формального параметра настройки вида in не должен быть ли­митируемым и, следовательно, не может быть заданным типом.

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