Н. Джехани - Язык Ада (1988) (1160771), страница 102
Текст из файла (страница 102)
9.10. ОПЕРАТОРЫ ПРЕКРАЩЕНИЯ Оператор прекращения переводит одну или несколько задач в аварийное состояние, предотвращая любые дальнейшие рандеву с такими задачами. оператор прекращения;:= аЬоп имя задачи (, имя задачи); При определении типа имени каждой задачи используется тот факт, что зто задачный тип. При выполнении оператора прекращения заданные имена задач вычисляются в порядке, который в языке не определен, Затем каждая упомянутая задача становится аварийной, если она еще не завершена; аналогично любая зависящая от упомянутой задача становится также аварийной, если она еще не завершена.
Любая аварийная задача, выполнение которой приостановлено операторами принятия, отбора или задержки, становится законченной. Любая аварийная задача, выполнение которой приостановлено прй вызове входа, а соответствующее рандеву еше не началось, становится законченной и удаляется из очереди к входу. Любая аварийная задача, которая не начала свою активизацию, становится законченной (и, следовательно, завершенной).
Этим заканчивается выполнение оператора прекращения. Окончание любой другой аварийной задачи не производится до окончания выполнения оператора прекращения. Оно должно произойти не позднее достижения аварийной задачей точки синхронизации, которой может быть конец ев активизации, начало активизации другой задачи, вызов входа, начало или конец выполнения оператора принятия, оператор отбора, оператор задержки, обработчик исключения или оператор прекращения. Если задача, вызвав.
шая вход, становится аварийной в ходе рандеву, то ее завершение не производится до окончания рандеву (см. 11.5). Вызов входа аварийной задачи возбуждает в месте вызова исключение ТАЗК1МО ЕЛЯОЛ. Аналогично исключение ТАВК)МО ЕЙЯОЛ возбуждается в любой задаче, вызвавшей вход аварийной задачи, если вызов входа все еще находится в очереди либо рандеву не окончено (вызовом входа может быть либо оператор вызова входа, либо операторы условного ипи вре. 412 Глава 9 меннбго вызова входа); исключение возбуждается не позже окончания аварииной задачи. Для любой аварииной (или законченной) задачи значение атрибута СА(.(.АВ(.Е есть РАСЗЕ. Если аварийное окончание задачи произошло во время изменения в задаче некоторой пе.
ременной, то значение атон переменной не определено. Пример: явен 08Ея, ТЕЛМ1МАЫай, РООь(3); Примечание. Оператор прекращения следует использовать только в крайних случаях, требующих безусловного завершения. Допускается, что задача может прекратить любую задачу, включая себя самое. Ссылки: аварийное состояние при рандеву 11.5, активизация 9.3, атрибут 4.1.4, атрибут САЕ( АВВЕ 9.9, временной вызов входа 9.7.3, завершенная задача 9.4, зависимая задача 9.4, за.
дача 9, значение логического типа РА(.ВЕ 3.5.3, имя 4.1, исключение ТАВК(НО ЕВВОЯ 11.1, обработка имени 4.1, обработчик исключения 11.2, оператор 5, оператор вызова входа 9.5, оператор задержки 9.6, оператор отбора 9.7, оператор принятия 9.5, очередь вызовов входов 9.5, рандеву 9.5, условный вызов входа 9.7.2. 9Д1. РАЗДЕЛЯЕМЫЕ ПЕРЕМЕННЫЕ Обычными средствами передачи данных между задачами являются операторы вызова и принятия входов. Если две задачи считывают или изменяют разделяемую переменную (доступную обеим задачам), то ни одна из них ничего не может знать о порядке выполнения операций нвд переменной в другой задаче, исключая точки их синхронизации. Две задачи синхрониэуются в начале и в конце их рандеву.
В начале и в конце своей активизации задача синхронизуется с вызвавшей эту активизацию задачей. Задача, которая закончила свое выполнение, синхронизуема с любой другой задачей. О действиях, выполняемых программой, использующей разделяемые переменные, всегда мокнут быть сделаны следующие предположения: ° Если в интервале времени между двумя точками синхронизации задача считывает разделяемую переменную скалярного или ссылочного типа, то эта переменная не изменяется ни. какой другой задачей в течение данного интервала времени. ° Если в интервале времени между двумя точками синхронизации задача изменяет разде. пяемую переменную скалярного или ссылочного типа, то эта переменная не считывается и не изменяется никакой другой задачей в течение данного интервала времени. Выполнение программы ошибочно, если какое-либо иэ этих предположений нарушено.
Если данная задача считывает значение разделяемой переменной, сделанные выше предположения допускают, чтобы реализация поддерживала локальные копии значения(например, в регистрах или в некоторых других видах временной памяти); и пока данная задача не достигла точки синхронизации ипи не изменила значение разделяемой переменной, следствием принятых допущений является то, что для данной задачи чтение локальной копии эквивалентно чтению собственно разделяемой переменной. Аналогично если данная задача изменяет значение разделяемой переменной, сделанные предположения допускают, чтобы реализация поддерживала локальные копии значения и откладывала запоминание локальной копии в разделяемую переменную до точки синхронизации, заменяя каждые последующие считывание нли изменения значений разделяемой переменной на считывание или изменение локальной копии. С другой стороны, не допускается, чтобы реализация вводила такую память, которая не будет обрабатываться в каноническом порядке (см.
11.6). Для задания того, что каждое считывание или изменение значения разделяемой переменной является для этой переменной точкой синхронизации, может быть использована прагма ВНАЯЕО, т.е. для данной переменной (но не обязательно для остальных) сделанных выше предположения справедливы. Форма этой прагмы следующая: ргайгла ВНАЯЕО (простое имя переменной); Прагма допустима только для переменной, объявленной описанием объекта скалярного или ссылочного типа; описание переменной и прагма должны помещаться (в таком порядке) непосредственно в одном и том же разделе описаний илн в спецификации пакета; прагма должна появиться до любого вхождения имени переменной, отличного от вхождения в спецификаторе адреса.
413 Задачи Реализация должна ограничивать объекты, для которых допустима прагма ЗНАЯЕО, объектами, для которых каждое прямое считывание или прямое изменение реализуется неделимыми операциями. Ссылки: активизация 9.3, глобальныи 8.1, задача 9, изменение значение 6.2, каноническии порядок 11.6, оператор вызова входа 9.5, оператор принятия 9.5, ошибочныи 1.6, переменная 3.2.1, прагма 2.8, присваивание 5.2, простое имя 3.1, 4,1, раздел описаний 3.9, рандеву 9.5, спецификация пакета 7.1, тип 3.3, чтение значения 6.2. 9.12. ПРИМЕР ИСПОЛЬЗОВАНИЯ ЗАДАЧИ В следующем примере определена задача буферизации для сглаживания различий между скоростью ввода производящей задачи и скоростью ввода некоторой потребляющей задачи.
Например, производящая задача может содержать операторы: Мор -- выработка следующего символа снля В О РЕЕВ,УУВ 1ТЕ(СНАЯ); аха вдмп СНАЯ = АЗСП.ЕОТ; епд Мор; потребляющая задача — операторы; Мор ВОРРЕВ.ВЕАО(СНАМ; — использование символа СНАЯ вчн ччьеп СНАЯ = АЗСП.ЕОТ; впд 1оор; Задача буферизации содержит внутренний пул для символов, обрабатываемых циклически. Пуп имеет два индекса: (М (МОЕХ, указывающий место следующего вводимого символа, и СОТ 1МОЕХ, указывающий место следующего выводимого символа.
!вез ВОРРЕЯ 1 ° впьу ЯЕАО (С: ое! СНАВАСТЕЯ); еппу УУВ1ТЕ(С: )п СНАВАСТЕВ); епд; гааз Ьоду ВОРРЕВ 1 ° РОЮ~ 8!2Е: сопмап! (МТЕОЕй: 100; : апет(! .. РОС) 8126) о! СНАйАСТЕй; СООМТ: 1МТЕОЕВ чапае О .. Р001 812Е:= 0: ПЧ !МОЕХ, ООт )МОЕХ г Путвйвй В 1 .. РООЬ.
8126:= 1: Ьеепг 1оор аа1ос! ччьеп СООМТ < Р001 8!ЕЕ => ассар! УЧЯ)ТЕ(С: (п СНАЯАСТЕВ) до РООИ1М )МОЕХ):= С; апд; 1М !МОЕХ:= )М )МОЕХ пмд Р001 8!ЕЕ + 1; СООМТ;= СООМТ + 1; ог ччьап СООМТ > О => ассар! ЯЕАО(С: оа! СНАЯАСТЕВ) до С:= РООИООТ 1МОЕХ); апд: ООТ 1МОЕХ:= ООТ )МОЕХ мод Р001 8!ЕЕ + 1: СООМТ:= СООМТ - 1; ог мпыпме: впд ав)аа: епд Ьо епд ВОРРЕВ; Глава 10 СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ В этой главе описываются общая структура программы и средства раздельной компиляции.
Программа представляет собой набор из одного нли нескольких компилируемых модулей, подаваемых на вход компилятора в виде одной или нескольких компиляций. Каждый компилируемый модуль определяет раздельную компиляцию некоторой конструкции.
Ею может быть описание или тело подпрограммы, описание или тело пакета, описание или тело на. страиваемого модуля или же конкретизация настройки. Кроме того, компилируемый модуль может быть субмодупем, т.е. телом подпрограммы, пакета, задачи, или настраиваемым модулем, описанным внутри другого компилируемого модуля. Ссылки: задача 9, компилируемый модуль 10.1, компиляция 10.1, конкретизация настройки 12.3, настраиваемое тело 12.2, описание настройки 12.1, описание пакета 7.1, описание подпро. граммы 6.1, субмодуль 10.2, тело задачи 9.1, тело пакета 7,1, тело подпрограммы 6.3. 10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ Текст программы может подаваться на вход компилятора в виде одной или нескольких компиляций.
Каждая компиляция представляет, собой последовательность компилируемых модулей. компиляция с = (компилируемый модуль) компилируемый модуль:: = спецификатор контекста ( спецификатор контекста библиотечный модуль вторичный модуль библиотечный модуль;:= описание подпрограммы ( описание пакета ( описание настройки ( конкретизация настройки ( тело подпрограммы вторичный модуль с= тело библиотечного модуля ( субмодуль тело библиотечного модуля::= тело подпрограммы ( тело пакета Говорят, что компилируемые модули программы принадлежат программной библиотеке. Компирируемый модуль определяет библиотечный модуль или вторичный модуль. Вторичный модуль — это раздельно компилируемое соответствующее тело библиотечного модуля или субмодуль другого компилируемого модуля. Обозначением раздельно компилируемой подпрограммы (библиотечного модуля или субмодуля) должен быть идентификатор.