Пакет STANDARD образует зону описания, которая охватывает каждый библиотечный модуль и, следовательно, главную программу; предполагается, что описание каждого библиотечного модуля находится непосредственно в этом пакете. Предполагается также, что неявные описания библиотечных модулей упорядочены таким образом, что область действия данного библиотечного модуля включает в себя любой компилируемый модуль, который упоминает в спецификаторе совместности этот библиотечный модуль. Однако видимыми внутри данного компилируемого модуля являются только такие библиотечные модули, которые упомянуты во всех спецификаторах совместности, относящихся к данному модулю, и тот библиотечный модуль, по отношению к которому данный модуль является вторичным модулем.
Примечание. Если все вложенные операторы блока программы поименованы, то имя каждого программного модуля, вложенного в блок, всегда может быть записано как расширенное имя, начинающееся с идентификатора STANDARD (в случае, когда этот пакет не является скрытым) .
Если тип описан в видимом разделе библиотечного пакета, то из правил видимости следует, что базовая операция (например, присваивание) над этим типом непосредственно видима в точке, где сам тип невидим (ни по имени, ни непосредственно) . Однако эта операция может быть применена только к тем операндам, которые являются видимыми, и описание этих операндов требует видимости либо типа, либо одного из его подтипов.
Контекст разрешения совмещения
Совмещение определено для подпрограмм, литералов перечисления, символов операций и одиночных входов, а также для тех операций, которые присущи обычным базовым операциям, например, присваивание, проверка принадлежности, генератор, литерал null, агрегаты и строковые литералы.
Для совмещенных понятий разрешение совмещения определяет фактический смысл, который имеет вхождение идентификатора, когда в соответствии с правилами видимости выясняется, что в месте этого вхождения приемлема более чем одна трактовка идентификатора; аналогичным образом разрешение совмещения определяет фактическую трактовку вхождения операции или некоторой базовой операции.
В таком месте рассматриваются все видимые описания. Вхождение правильно только тогда, когда есть точно одна интерпретация для каждого элемента самого вложенного полного контекста. Полный контекст — это:
описание;
оператор;
спецификатор представления.
При рассмотрении возможных интерпретаций полного контекста учитываются только те правила, которые касаются синтаксиса, области действия и видимости, а также те, которые даны ниже. Учитываются:
любое правило, которое требует, чтобы имя или выражение имели определенный тип или такой же тип, как другое имя или выражение;
любое правило, которое требует, чтобы тип имени или выражения был типом определенного класса; аналогично, любое правило, которое требует, чтобы определенный тип был дискретным, целым, вещественным, универсальным, символьным, логическим или нелимитируемым типом;
любое правило, которое требует, чтобы префикс соответствовал определенному типу;
любое правило, которое задает определенный тип в качестве типа результата базовой операции, и любое правило, которое устанавливает, что это тип определенного класса;
правила, которые требуют, чтобы тип агрегата или строкового литерала был определен исключительно охватывающим полным контекстом (см. разд. 4.3 и 4.2). Аналогично, правила, которые требуют, чтобы тип префикса атрибута, тип выражения оператора выбора или тип операнда преобразования типа были определены независимо от контекста (см. разд. 4.1.4, 5.4,4.6 и 6.4.1);
правила, данные в разд. 6.6 по разрешению вызовов совмещенных подпрограмм, в разд. 4.6 по неявным преобразованиям универсальных выражений, в разд. 3.6.1 по интерпретации дискретных диапазонов с границами, имеющими универсальный тип, в разд. 4.1.3 по интерпретации расширенного имени, чей префикс обозначает подпрограмму или оператор принятия.
Для имен подпрограмм, используемых в качестве аргументов прагмы, следуют ^другому правилу: прагма может применяться для нескольких совмещенных подпрограмм, как пояснено в разд, 6.3,2 для прагмы INLINE, в разд. 11.7 для прагмы SUPPRESS и в разд. 13.9 для прагмы INTERFACE.
Аналогично этому, данные в спецификаторах контекста (см. разд. 10.1.1) и спецификаторах адреса простые имена следуют другим правилам.
Примечание. Если существует только одна возможная интерпретация, то идентификатор обозначает соответствующее понятие. Однако данное утверждение не означает, что это вхождение обязательно правильно, так как существуют другие требования, которые не учитываются при разрешении совмещения; например, является ли выражение статическим, каковы виды параметров, является ли объект константой, выполняются ли правила согласования, является ли вхождение в спецификатор представления предписывающим, каков порядок предвыполнения и т. п.
Аналогично, при разрешении совмещения не учитываются подтипы. (Нарушение ограничения не делает программу неправильной, но возбуждает исключение во время выполнения программы).
Спецификация параметра цикла есть описание и, следовательно, полный контекст.
Правила, которые требуют, чтобы определенные конструкции имели один и тот же профиль параметров и типа результата, подпадают под категорию а; то же справедливо для правил, которые требуют согласования двух конструкций, так как это согласование требует в свою очередь, чтобы соответствующие имена имели одинаковый смысл, определенный правилами видимости и совмещения.
9. ЗАДАЧИ
Выполнение программы без задач определено в терминах последовательного выполнения ее действий в соответствии с правилами, сформулированными в других главах данного стандарта. Можно предположить, что эти действия выполняются одним логическим процессором.
Под параллельным выполнением задач понимают следующее. Предполагается, что каждую задачу выполняет отдельный логический процессор. Различные задачи (на различных логических процессорах) выполняются независимо, за исключением точек их синхронизации.
Некоторые задачи могут иметь входы. Вход задачи может быть вызван другими задачами. Задача принимает вызов одного из своих входов выполнением оператора принятия этого входа. Синхронизация достигается посредством рандеву между задачей, вызывающей вход, и задачей, принимающей вызов. Некоторые входы имеют параметры; вызовы входов и операторы принятия таких входов являются основным средством обмена значениями между задачами.
Свойства каждой задачи определяются соответствующим заданным модулем, который состоит из спецификации задачи и тела задачи. Заданные модули представляют собой одну из четырех форм программных модулей, из которых может состоять программа. Другие три формы — это подпрограммы, пакеты и настраиваемые модули. В данной главе описываются свойства заданных модулей, задач и входов и операторы, влияющие на взаимодействие задач (т. е. операторы вызова входов, операторы принятия, операторы задержки, операторы отбора и операторы прекращения).
Примечание. Параллельные задачи (параллельные логические процессоры) могут быть реализованы на многомашинных комплексах, многопроцессорных ЭВМ или чередующимся выполнением на одном физическом процессоре. С другой стороны, если реализация способна определить, что тот же результат получается при параллельном выполнении частей одной задачи на различных физических процессорах, то можно принять и такой способ выполнения; в этом случае несколько физических процессоров реализуют один логический процессор.
Спецификации задач и тела задач
Заданный модуль состоит из спецификации задачи и тела задали. Спецификация задачи, которая начинается зарезервированными словами 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 ЗАЩИЩЕННЫЙ-МАССИВ;
Примечание. Спецификация задачи задает интерфейс задачам данного типа с другими задачами тех же или различных типов, а также с главной программой.
Заданные типы и заданные объекты
Заданный тип является лимитируемым типом (см. 7.4.4). Следовательно, для объектов заданного типа не определены ни присваивание, ни предопределенное сравнение на равенство и неравенство; более того, вид out не допустим для формального параметра заданного типа.
Задачный объект — это объект заданного типа. Значение заданного объекта указывает задачу со входами соответствующего задачного типа, а ее выполнение определено соответствующим телом задачи. Если заданный объект является объектом или подкомпонентом объекта, заданными описанием объекта, то его значение определяется предвыполнением описания объекта. Если заданный объект является объектом или подкомпонентом объекта, созданными при выполнении генератора, то его значение определяется выполнением генератора. Для всех видов параметров, если фактический параметр указыавет задачу, сопоставляемый формальный параметр указывает ту же задачу; это же относится к подкомпоненту фактического параметра и к соответствующему подкомпоненту сопоставляемого формального параметра; наконец, то же справедливо и для параметров настройки.
Примеры:
УПРАВЛЕНИЕ: РЕСУРС;
ТЕЛЕТАЙП: ДРАЙВЕР_КЛАВИАТУРЫ;
ПУЛ: array (1. .10) of ДРАЙВЕР_КЛАВИАТУРЫ;
- - см. также примеры описаний одиночных задач в 9.1
Пример ссылочного типа, указывающего заданный объект:
type КЛАВИАТУРА is access ДРАЙВЕР_КЛАВНАТУРЫ;
ТЕРМИНАЛ: КЛАВИАТУРА: = new ДРАЙВЕР_КЛАВИАТУРЫ;
Примечание. Поскольку задачный тип является лимитируемым, он может появиться как определение лимитируемого личного типа в личном разделе и как фактический параметр настройки, сопоставляемый формальному параметру лимитируемого типа. С другой стороны, тип формального параметра настройки вида in не должен быть лимитируемым и, следовательно, не может быть заданным типом.
Заданные объекты ведут себя как константы (задачный объект всегда указывает одну и ту же задачу), поскольку их значения неявно определены либо при описании, либо при генерации, либо при сопоставлении параметров, и никакие присваивания недопустимы. Однако зарезервированное слово constant недопустимо в описании задачного объекта, так как его наличие требует явной инициализации. Задачный объект, который является формальным параметром вида in, есть константа (как и любой формальный параметр вида in).