автореферат диссертации по информатике, вычислительной технике и управлению, 05.13.11, диссертация на тему:Расширение языков программирования средствами обработки исключительных ситуаций

кандидата физико-математических наук
Бурцев, Алексей Анатольевич
город
Москва
год
1996
специальность ВАК РФ
05.13.11
Автореферат по информатике, вычислительной технике и управлению на тему «Расширение языков программирования средствами обработки исключительных ситуаций»

Автореферат диссертации по теме "Расширение языков программирования средствами обработки исключительных ситуаций"

' МОСКОВСКИЙ ОРДЕНА ЛЕНИНА, ОРДЕНА ОКТЯБРЬСКОЙ РЕВОЛЮЦИИ И ОРДЕНА ТРУДОВОГО КРАСНОГО ЗНАМЕНИ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИМ. М.В. ЛОМОНОСОВА

Факультет вычислительной математики и кибернетики

На правах рукописи

УДК 681.3.068

БУРЦЕВ АЛЕКСЕЙ АНАТОЛЬЕВИЧ

РАСШИРЕНИЕ ЯЗЫКОВ ПРОГРАММИРОВАНИЯ СРЕДСТВАМИ ОБРАБОТКИ ИСКЛЮЧИТЕЛЬНЫХ СИТУАЦИЙ

Специальность 05.13.11 - математическое и программное обеспечение вычислительных машин, комплексов, систем и сетей.

АВТОРЕФЕРАТ

диссертации на соискание ученой степени кандидата физико-математических наук

МОСКВА 1996

Работа выполнена на кафедре Автоматизации систем вычислительных комплексов факультета Вычислительной математики и кибернетики Московского государственного университета имени М.В. Ломоносова.

Научный руководитель:

кандидат технических наук,

старший научный сотрудник С.П.МАСЛОВ

Официальные оппоненты:

доктор физико-математических наук,

профессор Э.3.ЛЮБИМСКИЙ

кандидат физико-математических наук М.Н.ШУМАКОВ

Ведущая организация: Институт Системного программирования

' РАН (г. Москва)

Защита состоится ¿¿¿Гр^ 199£г. в .Йчасов _&Оушя.

на заседании специализированного Совета Д.053.05.38 Н4 по математике при МГУ им. М.В. Ломоносова по адресу: 119899, ГСП, Москва, В-234, Воробьевы горы, МГУ. ^&культет вычислительной математики и кибернетики, аудитория

С диссертацией можно ознакомиться в библиотеке факультета Вычислительной математики и кибернетики ИГУ.

Автореферат разослан "22" .

Ученый секретарь специализированного совета профессор

Н.П.ТРИФОНОВ

- 3 -

ОБЩАЯ ХАРАКТЕРИСТИКА РАБОТЫ

Актуальность проблемы. Для современного этапа развития информатики характерно расширение таких областей применения цифровых ма-шш. в которых компьютерная система должна работать непрерывно в течение длительного срока. К их числу, в частности, относятся диалоговые системы, рассчитанные на массового пользователя, и системы управления, рассчитанные на длительное функционирование без вмешательства человека. Характерная особенность этих применений состоит в том, что их программное оснащение должно надежно функционировать даже в условиях чрезвычайных обстоятельств (нештатных ситуаций), возникающих в результате ошибок пользователя или по причине нарушений в работе аппаратных средств. Учет всевозможных ситуаций, которые могут возникнуть в процессе работы программного комплекса, в том числе и тех. которые не должны возникать при его нормальном (штатном) функционировании, приводит к значительному усложнению программной разработки.

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

Цель диссертационного исследования. Основными целями работы явились: анализ методов разработки программ с учетом обработки нештатных ситуаций; исследование путей внедрения в языки программирования специального управляющего механизма - механизма исключительных ситуаций, позволяющего снизить трудоемкость разработки программ, учитывающих возникновение нештатных ситуаций; разработка такого механизма для ДССП - диалоговой системы структурированного программирования; разработка механизма исключительных ситуаций для языка ТурбоПаскаль, широко используемого в учебном процессе.

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

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

Практическая ценность. В результате диссертационной работы создан механизм ситуаций для ДССП - Диалоговой системы структурированного программирования, разработанной в проблемной лаборатории ЭВМ факультета ВМК МГУ; а также реализован модуль, обеспечивающий средства обработки исключительных ситуаций для языка программирования ТурбоПаскаль.

Апробация работы. Результаты исследований и разработок, представленных в работе, обсуждались на научных семинарах кафедры АСЕК и проблемной лаборатории ЭВМ МГУ, докладывались на конференциях молодых ученых факультета ВМК МГУ и Обнинского института атомной энергетики.

Объем диссертации. Диссертационная работа состоит из введения, четырех глав, заключения и приложений. Основной текст диссертации (без приложений) занимает 106 машинописных страниц. Список литературы содержит 120 наименований.

СОДЕРЖАНИЕ РАБОТЫ

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

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

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

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

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

При разработке программ с использованием обычных средств языка программирования применяются следующие традиционные способы обработки нештатных ситуаций : 1) аварийный останов; .2) регулярные проверки кода завершения операции с последующи™ ветвлениями в программе; 3) переход по заданной метке или адресу, определяемому меточной переменкой; 4) вызов назначенной процедуры обработки с возможностью последующего выхода из нескольких вложенных блоков.

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

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

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

- б -

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

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

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

Какой бы способ программирования и механизм языка, его поддерживающий, ни использовался для обработки нештатных ситуаций, в целях достижения эффективности и надежности разрабатываемой программы, он должен удовлетворять следующим требованиям:

1) должен быть прост для понимания и использования;

2) не должен загромождать тело нормального поведения программы;

3) не должен замедлять нормального функционирования программы;

4) должен позволять единообразно обрабатывать нештатную ситуацию независимо от того, как она обнаружена (программно или аппаратно);

5) должен позволять программировать действия, направленные на восстановление работоспособного состояния программы и дальнейшее ее продолжение.

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

внедряемого в настоящее время в языки программирования. Этот механизм получил название механизма обработки исключительных ситуаций (mechanism for exception handling). Для краткости его называют также механизмом исключений, исключительных ситуаций или просто механизмом ситуаций.

Чтобы разрабатывать структурированные программы (т.е. программы с четко выраженной структурой, которая дает ясное представление о динамике ее выполнения), в языки программирования в свое время были внедрены такие конструкции управления, как if . while, case и им подобные, называемые структурированными управляющими конструкциями. Использование таких конструкций позволяет значительно снизить трудоемкость разработки и повысить надежность создаваемых программ для широкого круга задач. Аналогично управляющие конструкции механизма исключений призваны поддержать структурированное построение программ, вынужденных обеспечивать обработку особых ситуаций. Механизм исключений позволяет придать такой программе ясную структуру, отражающую динамику ее поведения как при нормальном (штатном) функционировании, так н в условиях возникновения особых (нештатных) ситуаций.

Ситуация, которую предполагается особым образом обрабатывать в программе, в терминах этого механизма называется исключительной (сокращенно И-ситуация) или исключением (exception). Управляющие конструкции механизма исключений позволяют расщепить алгоритм программы (равно как и любой подпрограммы, блока) на основной фрагмент, выражающий его поведение в нормальных условиях, и один или несколько фрагментов, каждый из которых описывает обработку той или иной исключительной ситуации. Предопределяется, что выполнение алгоритма начинается с основного фрагмента и продолжается в нем (до конца), если никаких исключительных ситуаций не возникает. Переключение на фрагмент обработки конкретной исключительной ситуации осуществляется только тогда, когда эта ситуация возникает при выполнении основного фрагмента.

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

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

В качестве базовой в диссертации излагается концепция механизма исключений, заимствованная из книги Янга "Алгоритмические языки реального времени". Рассматриваются основные понятия и возможности механизма исключений, объясняются правила его функционирования в программе с вложенными блоками.

Возникновение исключительной ситуации в программе воспринимается как возбуждение исключения, под которым понимается действие, сигнализирующее о наличии исключения в программе. Новое исключение объявляется как переменная специального типа Exception : var Е : Exception ( где Е - имя нового исключения } Для некоторых, так называемых предопределенных исключений, которые возбуждаются не самой программой, а ее окружением, имена уже зарезервированы, и их объявлять не надо. Например. ZeroDivide (попытка деления на ноль), FileError (ошибка при работе с файлом ).

Исключение может быть возбуждено неявно (окружением программы) или явно в самой программе. Для возбуждения исключения предусматривается специальный оператор вида: raise Е , который следует выполнять в программе, когда обнаружена И-ситуация, например: if "обнаружена И-ситуация" then raise Е ; Участок программы, который должен расщепляться на основное тело. выражающее поведение программы в нормальных условиях, и альтернативное тело, которое используется только в случае возбуждения исключения, называется далее расщепленным блоком ( сокращенно Р-блоком ) и оформляется в следующем виде:

begin { основное тело )

<ряд операторов> except {альтернативное тело) Е: <ряд операторов); ( обработчик исключения Е ) Е1.Е2: <ряд операторов) { обработчик исключений Е1.Е2 ) others: <ряд операторов) { обработчик остальных исключений ) end

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

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

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

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

В действительности, механизм исключений предусматривает более сложные действия при возбуждении исключения в программах с блочной структурой (см. рис. 2), где одни программные блоки при своем выполнении вызывают другие блоки, и в результате один блок (А) оказывается вложенным (при выполнении программы > в другой (В), а тот в свою очередь в третий (С) и т.д. причем среди этих блоков, вложенных друг в друга подобно матрешкам, могут оказаться как обычные (или процедурные) блоки (А.Н,Р). так и расщепленные (Р-блоки В.С.М), в которых предусматриваются реакции на исключения.

Во вложенных блоках (см. М. С) могут быть установлены реакции на одно и то же исключение (Е). которые будем называть вложенными (по аналогии с вложенными блоками, где они определены). Какие действия будут вызваны возбуждением исключения, на которое установлено несколько вложенных реакций ? Какой конкретно обработчик будет вызван для исключения (Е), реакция на которое предусмотрена более чем в

var Е,Е1,Ex : Exception;

begin....

... raiseE;... except

ее* handler i E: E-handier;

E1: E1-handler;

Ex: Ex-handier; end;

рис. 1. Схема выполнения расщепленного блока (Р-блока).

/-ЕХЛ

Exception handler

CE

(M

Г

w.

H

m

4Z.

СК

Э

Y E: (^хГмЕ^

3

A

Çç—yztm

>

У

var E,Ex:

Exception; procedure M;

begin • ■. except

E:ME: Ex:MEx;

end;

procedure C;

begin • • • except E:CE; raise; end;

procedure B;

begin... except

Ex:BEx; ena:

procedure A;

begin ... raise E; en?j;

рис. 2. Схема распространения исключения в программе с вложенными блоками.

одной из вложенных блоков (С.М)? И что произойдет, если оно будет возбуждено в ходе выполнения блока (А), где для этого исключения обработчик не установлен? Чтобы можно было однозначно разрешить подобные вопросы, объясним действия рассматриваемого механизма при возбуждении исключения в форме следующих правил.

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

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

2. После выполнения обработки исключения блок, где встречен этот обработчик, завершается вместе со всеми блоками, вызванными им, а выполнение программы продолжается с той точки, где был вызван завершенный блок.

3. По окончании обработки исключения в текущем блоке его можно распространить явно в охватывающий блок путем повторного его возбуждения в обработчике этого исключения текущего блока. Для повторного возбуждения обрабатываемого исключения можно применять сокращенную форму оператора возбуждения: raise (без параметров).

Приведенный пример демонстрирует это правило: исключение Е повторно возбуждается в обработчике СЕ и распространяется далее в блок Н, а затем в блок М, где встречает обработчика НЕ. Таким образом, в результате распространения исключения разрешается в нескольких вложенных блоках задать свои реакции на него и обеспечить тем самым многоуровневую обработку одного и того же исключения'.

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

Заметим, что согласно сформулированным правилам порядок действия вложенных реакций, установленных на одно и то же исключение, регулируется по тому же принципу стека (LIFO), который определяет

и порядок выполнения вложенных подпрограмм.

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

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

Механизм исключительных ситуаций в зачаточном виде появился еще в языке ПЛ/1, где он использовался, в основном, как средство реакции на прерывания и другие события, возникающие в операционной среде при выполнении погружаемой в нее программы. В дальнейшем в таких языках, как Автокод Эльбрус, Ада. CHILL, CLU, Mesa он получил качественно новую трактовку как средство структурирования программы, в которой требуется обрабатывать аномальные ситуации. Доказательством полезности этого механизма можно считать не только появление его в новых языках (С++, Delphi), но и попытки добавления его в языки, уже получившие широкое распространение (Бейсик, Си, Модула-2).

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

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

Если нужный способ продолжения программы не обеспечивается са-

ним механизмом, ситуаций, то для его реализации приходится использовать дополнительные операторы передачи управления ( goto, exit, restart и т.п.). В целях повышения надежности разрабатываемых программ предпочтительнее иметь механизм ситуаций, который поддерживает все три типа реакций: 1) с возвратом в точку возбуждения после выполнения блока-обработчика ситуации (тип Hotify); 2) с прекращением блока, в котором был найден обработчик ситуации (тип Escape); 3) с возобновлением блока, где найден обработчик ситуации (тип Retry). Показано, что такой "универсальный" механизм является достаточным, чтобы обеспечить любое возможное продолжение программы после обработки ситуации.

Встречаются две формы установки реакций: в первой используется специальный оператор для динамического связывания реакции с ситуацией; во второй - специальная синтаксическая конструкция в виде расширенной формы составного оператора, в заключительной части которой определяются действия по обработке ситуации. Первая форма используется в языке ПЛ/1, где реакция на ситуацию задается оператором ОН, который устанавливает действие заданной реакции до конца текущего блока. Вторая форма используется в языке Ада. где обработчики ситуаций (исключений) помещаются в конце блока, подпрограммы, пакета, или тела задачи вслед за ключевым словом exception. Аналогичная синтаксическая конструкция используется и в автокоде Эльбрус (структурное предложение), в языке С++ (контролируемый блок), в языке Delphi (защищенный блок).

Для возбуждения ситуации используется особый оператор, который выделяется специальным ключевым словом (raise в Аде, SIGNAL в ПЛ/1, throw в С++) или знаком (в автокоде Эльбрус он называется структурным переходом и обозначается восклицательным знаком, стоящим вслед за именем ситуации), либо выглядит в форме вызова подпрограммы (exc_raise для Си, Raise для Модулы-2 ).

Благодаря обширному ассортименту встроенных исключительных ситуаций, предусмотренных в языке, программе предоставляется возможность по-своему реагировать на разнообразные события, возникающие в ее программном и аппаратном окружении. Ассортимент таких ситуаций. которые могут возбуждаться неявно при выполнении отдельных операторов, можно, как правило, регулировать при компиляции программы ( установкой префиксов-перед операторами в ПЛ/1, директивами SUPRESS в Аде).

Для построения программ с наглядной структурой выделение исклю-

чительных ситуаций может играть такую же важную роль, как и выделение вспомогательных подпрограмм. А механизм исключений можно использовать как базовый управляющий механизм наравне с такими управляющими конструкциями как цикл, ветвление, вызов подпрограммы. Но для этого необходимо иметь возможность расширять ассортимент ситуаций, применяемых в программе, так же легко, как расширять, набор применяемых подпрограмм. Объявление новых исключительных ситуаций затруднено лишь в языке ПЛ/1 (а в подмножестве ПЛ/1 не разрешается вообще). В других языках оно разрешается в форме объявления переменных специального типа (exception в Аде), либо в форме определения подпрограмм особого вида (sequel, вызывающих завершение блока, в котором они объявлены) или в форме объявления новых классов объектов (С++, Delphi).

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

В языке ПЛ/1 лишь некоторые встроенные ситуации имеют параметр: им может быть имя файла (ENDFILE). Входные параметры ситуации разрешены в автокоде Эльбрус, где оператор возбуждения ситуации (структурный переход) синтаксически похож на вызов процедуры со списком фактических параметров, а обработчик ситуации оформляется, как параметризованное действие со списком формальных параметров. В тех языках, где параметризация ситуаций не допускается (Ада), передачу информации между обработчиком ситуации и программной компонентой, возбудившей ее, приходится организовывать при помощи других менее пригодных для этого средств (например, через глобальные переменные).

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

Возможность реагировать на внешнее событие, как'на возбужденную ситуацию, была бы полезной и при организации взаимодействий параллельных процессов. Это позволило бы каждому программному процессу совершенно другим способом "узнавать" о событиях, возникающих в

других процессах. Но такая привлекательная возможность не обеспечивается в полной мере в языках, поддерживающих параллельное программирование. Часть из них вообще не имеет механизма ситуаций. В других он никак не связан с параллелизмом (ПЛ/1). А в языке Ада возможность возбудить исключение.в другой задаче очень ограничена.

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

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

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

Рассматриваются варианты усовершенствования механизма, обеспечивающие ускорение операции поиска ловушки. В результате выявляются ключевые действия механизма ситуаций, которые требуется обеспечивать во время выполнения программы: 1) формировать в стеке список ловушек ситуаций: добавлять ловушки при входе в защищенный блок и удалять их при выходе из него; 2) быстро находить в этом списке ближайшую ловушку для возбужденной ситуации; 3) восстанавливать программный контекст, в частности, свертывать стек активаций процедур до 'уровня, зафиксированного в момент установления найденной ловушки.

Реализацию механизма исключений можно выполнить не только на ассемблере, но и на уровне языка, в котором предусмотрена операция переключения контекста. В языке Си такая реализация возможна на основе функций длинного перехода зег^шр и ЮпеЗтр, а в языке Моду-ла-2 - на основе особой команды передачи управления сопрограмме.

Проведенный выше анализ позволяет сформулировать свойства механизма ситуаций современного языка программирования в форме следующих требований. Итак, механизм ситуаций должен : 1) предоставлять возможность объявлять новые (свои) ситуации так

- 16 -

же просто, как новые подпрограммы или переменные;

2) обеспечивать реакцию типа Escape (прекращения), а также поддерживать реакции типа Hotify (уведомления) и Retry (возобновления). исключая полностью потребность в операторе перехода в какой-либо форме;

3) позволять расщеплять любой блок для реакции на ситуацию;

4) разрешать вложенные реакции на одну и ту же ситуацию;

5) обеспечивать распространение и повторное возбуждение ситуации, допуская возможность ее многоуровневой обработки;

6) поддерживать динамические ситуации:

7) предоставлять возможность определения реакции по умолчанию (так называемой конечной реакции) для вновь объявляемой ситуации;

8) позволять параметризовывать ситуацию, обеспечивая при обработке ситуации передачу параметров любых видов: входных (In), выходных (out), модифицируемых (inout);

9) допускать передачу самой ситуации в качестве параметра;

10) обеспечивать возможность возбуждения произвольной ситуации по прерыванию или по требованию другого ( параллельного ) процесса:

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

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

Теоретически возможно несколько путей для внедрения новых средств в язык программирования. Первый путь связан с модификацией самого синтаксиса- базового языка. Он открывает широкие возможности выбора выразительных средств для представления в языке новых конструкций. но может быть реализован только при доступности исходного текста самого компилятора. Таким путем конструкции обработки исключительных ситуаций были введены в язык Basic.

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

Третий путь позволяет подключать новые средства на уровне моду-

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

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

В диссертации рассматривается, как эти возможности можно обеспечить в отдельном модуле для языка ТурбоПаскаль. Дается подробная характеристика предложенного модуля (ExMhnism) и объясняются ключевые моменты его реализации.

В этом модуле для представления исключительных ситуаций в программе определен новый тип данных (Exception) и предусмотрены процедуры, реализующие требуемые операции с ситуациями. Для работы с исключительной ситуацией S ее, прежде всего, нужно объявить в программе как переменную типа Exception : " var S : Exception " . Возбуждение ситуации S обеспечивается путем вызова подпрограммы RaiseEx(S), где в качестве параметра требуется указать имя возбуждаемой ситуации.' Повторно возбудить ту же ситуацию, которая возбуждалась последней, можно вызовом другой подпрограммы ReraiseEx (без параметров).

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

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

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

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

Для установки реакции на любую ситуацию (какай бы ни случилась) в модуле объявлена переменная типа Exception с предопределенным именем Апу. Если возбужденная снтуация будет распространяться в блок, расщепленный с помощью вызова WithoutEx(Any), то управление будет передано на альтернативную ветвь этого блока для обработки ситуации. А чтобы можно было узнать, какая же ситуация возникла, предлагается логическая функция theExceptionls(E). с помощью которой можно проверить, была ли возбуждена указанная ситуация (Е).

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

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

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

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

Подпрограмма WlthoutEx представляет собой логическую функцию с одним параметром - указателем ситуации. При ее обычном вызове она возвращает значение true. Восстановление контекста и подстановка значения false в качестве возвращаемого результата выполняется вспомогательной подпрограммой RaiseException. Она вызывается из процедур RaiseEx и ReraiseEx, а выход из нее обеспечивается в точку того вызова подпрограммы VfithoutEx, который устанавливал найденную ловушку.

Действия по сохранению контекста, выполняемые внутри WithoutEx, и действия по восстановлению этого контекста, выполняемые внутри RaiseException. требуют выполнения таких операций над регистрами и над системным стеком, которые не могут быть выражены операторами языка высокого уровня. Подробно поясняется, как как эти действия можно реализовать на встроенном ассемблере в среде языка ТурбоПас-каль для компьютеров на базе процессора Intel 8086.

Четвертая глава посвящена разработке механизма ситуаций для ДССП - диалоговой системы структурированного программирования, призванной снизить трудоемкость разработки программ для микрокомпьютеров. Дается краткая характеристика ДССП-процессора, как интерпретатора сшитого (threaded) кода, который принято называть также процедурным. Приводятся алгоритмы выполнения им команд, управляющих ходом исполнения программы, представленной в прямом процедурно!! коде. Рассматриваются команды предлагаемого механизма ситуаций и подробно описывается их реализация для ДССП-процессора.

Несомненным достоинством ДССП является легкость ее расширения: добавление новых операции осуществляется путем наращивания ее словаря. Так что внедрение новых возможностей в эту систему, как правило, сопровождается появлением новых слов в ее словаре.

Предлагаемый для ДССП механизм ситуаций расширяет ее систему комалд и обогащает ее язык рядом следующих новых слов: SITUATION, 0Н_, .ESCAPE. _RETRY, JJOTIFY. _RAISE. RERAISE. A1IY.

Команда SITUATIOH действует на этапе компиляции (как VAR) н позволяет определить новую ситуацию как переменную особого типа : SITUATIOH S FR

( S - имя новой ситуации, FR - имя процедуры конечной реакции ).. Эта определяющая команда создает дескриптор ситуации, указатель на

который используется далее для ее идентификации в тех операциях, где требуется ссылка на ситуацию.

Поместить указатель ситуации в стек можно командой 0Н_ : ... t 1 0N_ S [ 'S 1 ... которая позволяет передавать ситуацию в качестве параметра.

Для установки реакции на ситуацию используется одна из команд: ... [ 'S ] .ESCAPE RE [ ] ... ... C'S] _RETRY RE [ ] ... ... ['SI .NOTIFY RE [ 3 ...

( где 'S - указатель ситуации, который задается в вершине стека ) ( a RE - имя процедуры реакции, устанавливаемой этой командой ). В них отражена специфика команд управления, характерная для ДССП: тело реакции задается ссылкой на отдельную процедуру (RE) подобно тому, как это сделано в командах ветвлений и циклов.

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

Различие этих команд проявляется в типе устанавливаемой реакции, который фиксируется при формировании ловушки и определяет способ продолжения программы после обработки ситуации:

1) с точки возбуждения ситуации (NOTIFY );

2) с конца той процедуры, где была установлена реакция (ESCAPE);

3) с той точки, где была установлена выполненная реакция (RETRY). Ключевое слово AMY используется для установки реакции на любую

ситуацию. Выполнение процедуры, соответствующей имени ситуации, приводит к возбуждению этой ситуации. Командой RAISE :

... t 'S3 .RAISE [ ] ... можно возбудить ситуацию, указатель которой задан вершиной стека. Командой RERAISE можно повторно возбудить ситуацию, которая возбуждалась последней.

В диссертации объясняются основные решения, принятые при разработке механизма ситуаций. Подробно рассматриваются строение ловушек в стеке и алгоритм возбуждения ситуации.

Имеющийся в ДССП механизм прерываний не позволяет, вообще говоря. выполнять при обработке прерывания команды, изменяющие арифметический илн управляющий стек, если эти изменения затрагивают ту область, где выполнялись прерванные действия. К таким командам от-

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

При разработке механизма ситуаций был предложен другой способ выполнения прерывания ДССП-процессором. Вызов процедуры, обрабатывающей прерывание, выполняется не в момент ее возникновения, а позже, тогда, когда ДССП-процессор закончит исполнение текущей ДССП-команды (1-ый вариант) или даже серии команд (2-ой вариант), выполняемых в машинном коде. Предложенный механизм прерываний является более гибким, чем ранее принятый в ДССП, так как он позволяет выполнить по прерыванию любую команду (в том числе, команду возбуждения ситуации, команду возобновления требуемого процесса, а также возобновления процесса с возбуждением в нем ситуации). Подчеркивая главную особенность ноеого механизма, можно охарактеризовать его, как механизм, обеспечивающий прерывание на уровне интерпретатора процедурного кода.

В диссертации также объясняется, как в случае дополнения ДССП средствами параллельного программирования обеспечить возбуждение ситуации в одном параллельном процессе по требованию другого.

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

ЗАКЛЮЧЕНИЕ

Основные результаты диссертационной работы состоят в следующем:

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

2) предложен путь расширения языка высокого уровня средствами обработки исключительных ситуаций, основанный на подключении этих

средств к программе в форме раздельно компилируемого модуля, которым дополняется окружение языка;

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

4) разработан механизм ситуаций для стекового процессора, обеспечивающего функции интерпретатора программ, представленных в процедурном (сшитом) коде;

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

6) реализован вариант механизма ситуаций для стекового процессора Диалоговой Системы Структурированного Программирования (ДССП).

Автор выражает глубокую благодарность своему научному руководителю Маслову С.П. и руководителю проблемной лаборатории ЭВМ МГУ Брусенцову Н.П. за ценные советы и внимание к работе.

Результаты диссертации отражены в следующих печатных работах :

1. Бурцев A.A. Программное оснащение для работы с кассетным накопителем на магнитной ленте в диалоговой системе структурированного программирования.- В сб.: Программное оснащение микрокомпьютеров. М.: МГУ, 1982. с.65-74.

2. Бурцев A.A. Структурированное программирование управления периферией в минисистемах.- В кн.: Архитектура и программное оснащение цифровых систем. М.: ИГУ, 1984, с.27-32.

3. Бурцев A.A. Об одном подходе к разработке программного оснащения периферии в микрокомпьютерных системах.- В кн.: Методы решения задач математической физики и их программное обеспечение. М.: Изд-BO МГУ, 1984, с.94-96.

4. Бурцев A.A. Периферийный монитор диалоговой системы структурированного программирования для микрокомпьютеров. - В кн.: Прикладная математика и математическое обеспечение ЭВМ. М.: МГУ, 1985. с. 73-75.

5. Бурцев A.A. Периферийный монитор - развитие архитектуры ввода/вывода ДССП.- В кн.: Диалоговые микрокомпьютерные системы. М., МГУ. 1986. С.42-51.