Язык Ада, 05 лекция (от 24 марта)
Материал из eSyr's wiki.
Содержание |
Модульность
Дочерний пакет
Пусть есть пакет, который описывает комплексное число. Будем записать его как абстрактный тип данных. Определим операции арифметики. Также нужно записать функции для перевода обычных чисел и обратно. Тип комплекс – запись из двух полей. Допустим нужно добавить представление комплексного числа в тригонометрической форме. Нужно добавить функцию, получающую модуль комплексного числа и тд. Если мы находимся вне пакета, определяющего комплексные числа, то мы не знаем, как комплексное число устроено и реализовать комплексное число не можем. Возникла необходимость добавить дополнительные возможности не разрушая старых. Решить эту проблемы можно с помощью дочернего модуля, в котором мы будем определять тела функции со всеми подробностями реализации. Дочерний модуль, начиная с приватной части и до конца своего тела, видит информацию, расположенную в приватной части родителя. Дочерний пакет никому эту информацию предоставить не может. Эта технология дает возможность развивать защищенные абстракции в других модулях, не нарушая защиту. Дочерний пакет – не клиент этого пакета, а его развитие. Пусть есть файловая система. И есть понятие файл со своими свойствами. Для большинства клиентов понятие файла одинаково. Но есть особы типы файлов, которые нужны небольшому количеству клиентов. Например, исполняемый файл имеет особые свойства. При занесении в память его нельзя рвать на части и тд. Вынесем исполняемый файл в дочерний пакет. Только тем клиентам, которым это реально необходимо, стоит дописать дочерний модуль, в котором будет расширяться структура файла. При этом, если бы изменения были внесены в сам модуль, то пришлось бы перекомпилировать все программы, где он использовался, а так этого удается избежать. Т.е. «экзотику» стоит выносить из общей спецификации в дочерний модуль.
Правила видимости
Дочерний модуль рассматривается в контексте родителя. Сначала идет его видимые объявления, потом идут видимые объявления потомка, приватные объявления родителя, приватные объявления потомка. Можно считать, что тело дочернего модуля вставлено в самое начало тела родителя.
Сборка Адской программы
Как собирается программа? Можно считать, что существует один главный процесс. В нем в разделе объявления должны находиться все раздельно компилируемые модули. По Адской терминологии, если операторы выполняются, то объявления обрабатываются. Объявления переменной могут включать инициализацию, в качестве инициализирующего выражения может быть вызов функции. Если есть пакет, то у этого пакета в теле запускается раздел операторов, которые выполняются при обработке тела пакета. Возникает проблема выстроить модули составляющей программы корректным образом. Основные правила для выстраивания модулей корректным образом:
- Модули должны быть выстроены так, что каждое имя, когда оно используется, определено уже было.
- Должен быть корректный порядок обработки объявлений. Корректный порядок: нельзя вызывать подпрограмму до тех пор, пока ее тело не было обработано.
- Результат работы программы, если она неразумным образом составлена, может оказаться неопределенная. Реализация должна обеспечивать корректный порядок обработки. В правилах языка сказано, что выбирает произвольный корректный порядок обработки из возможных.
Асинхронные процессы
Проблемы при работе с асинхронными процессами:
- Запустить, закончить процесс
- Синхронизация процессов, которые асинхронны, обмен данных между ними
- Разделяемые ресурсы
- Тупиковые ситуации(например, при использовании буфером при обмене между поставщиком и потребителем)
- Приоритеты
Философия Ады в отношении асинхронных процессов:
- Полезны абстракции довольно высокого уровня, чтобы рассматривать набор процессов именно в терминах процессах и их поведения, а не в терминах специальных функций операционных систем.
- Предоставляемые языком средства должны хорошо согласовываться с привычной моделью асинхронных процессов.
- Ада ориентирована на концепцию внутренней дисциплины использования разделяемых ресурсов
Задачи – основной Адовский программный модуль, предназначенный для описания асинхронных процессов. Задачи имеет спецификацию и тело. Спецификация задачи описывает интерфейс работы с внешним миром, тело описывает сам процесс. Задача – типизированный объект. Задачи нельзя раздельно компилировать, они всегда куда-то вложены. Каждая спецификация задачи требует наличие типа. Написать только спецификацию и не написать тело нельзя – компилятор выдаст ошибку. Вложенность описания задач может быть любая, одна задача может быть в другой. Пусть мы попали в процесс. Происходит обработка объявлений. Перед тем, как начать выполняться первому оператору из процесса-хозяина, запускаются все остальные процессы. Запускающий процесс называют мастер-процессом. Пока не закончатся все запущенные задачи, мастер-процесс не завершается.
Обмен данными и синхронизация.
В спецификации может быть описание входа для общения с внешним миром. Описание входа похоже на описание процедуры. Если есть вход в задаче, то в теле задачи этому входу должен соответствовать как минимум один оператор приема входа. В нем между begin и end описывается то, что происходит при приеме входа. Вызывающая программа смотрит, готова ли вызываемая обслуживать вызов входа. Если не готова, то вызов становится в очередь вызовов к данному входу. Этот механизм получил названия ассиметричного рандеву. Вызывающий знает, кого он вызывает, а вызываемому все равно, кто его вызвал, тк обслужить – это выполнить оператор приема. Никаких следов от того, кто здесь был. Когда вы – клиент, вам нужно понимать, какой мастер вам нужен. Клиенту важно выбрать мастера, мастеру все равно, кто клиент, лишь бы по типу подходил.