Ада-95. Компилятор GNAT

       

Язык Ада - взгляд "сверху вниз"


Знакомство с языком программирования Ада можно осуществлять несколькими различными путями.

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

Теперь попытаемся рассмотреть процесс программирования, как процесс проектирования системы, то есть, воспользуемся принципом "сверху вниз".

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

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

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

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

Кроме того, это позволяет группам программистов создавать и управлять большими системами и программами с минимальными затратами.

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

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

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




Можно сказать, что пакет может быть единым менеджером над созданием и использованием объектов некоторого заданного типа.

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



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

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

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

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

Использование языка Ада для подсистем и прикладных задач заманчиво не только из-за возможности работы с пакетами.

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

Задачи в языке Ада могут создаваться (и прерываться) как статически, так и динамически.

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

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



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

При вызове подпрограммы внутри пакета нить управления "перемещается" по кодам, составляющим этот пакет.

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

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

Процесс порождения нитей управления может последовательно развиваться, образуя дерево задачи.

Окончание такой задачи может произойти только после окончания работы всех порожденных ею задач.

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

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

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

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

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

Если все завершается благополучно, то вызывающую задачу информируют о том, что сообщение было получено.

После этого вызывающая программа возобновляет свою работу.

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

Как мы уже знаем, такой протокол, включающий в себя временную остановку вызывающей задачи, называется рандеву.



При завершении рандеву вызывающая задача может снова начать выполнение, возможно, параллельно с вызванной ею задачей.

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

Использование рандеву и защищенных объектов гарантирует поддержание "структурности" программы в терминах "структурированного программирования".

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

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

Рассмотрим противоположную ситуацию на примере языка Паскаль.

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

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

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

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

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



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

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

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

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

Copyright (C) А.Гавва V-0.4w май 2004

Содержание раздела