Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Языки программирования. Концепции и принципы
.pdf
Асинхронные процессы
171
Защищенные разделяемые переменные – мониторы
task защищенная_переменная is
entry читать(X : out сообщение);
entry писать(X : in сообщение);
end защищенная_переменная;
task body защищенная_переменная is
Z : сообщение;
begin
loop
select
accept читать(X : out сообщение) do X:=Z end;
or
accept писать(X : in сообщение) do Z:=X end;
end select;
end loop;
end защищенная_переменная;
В сущности, это монитор, реализующий режим взаимного исключения для
процедур доступа к разделяемому ресурсу. Обратите внимание, что в полной мере
обеспечены синхронизация и исключение, но качество развязки зависит от реали
зации языка (формально исполнитель имеет право отбирать, например, всегда
первую альтернативу, даже если «второй» клиент давно ждет).
Лучше в этом смысле работает описанный ниже монитор «буф» (с дополни
тельными условиями отбора).
Монитор – буфер
with общий; use общий;
task буф is
entry передать(X : in сообщение);
entry получить(X : out сообщение);
end áóô;
Как было! Пользоваться так же удобно и надежно.
task body áóô is
begin
loop
select
when not полон =>
accept передать(X: in сообщение) do
занести(X);
end передать;
or
when not ïóñò =>
accept получить(X : out сообщение) do
выбрать(X);
end получить;
or
delay t;

172
end select;
end loop;
end áóô;
Итак, мы полностью смоделировали монитор ХансенаХоара посредством
рандеву. При этом семафоры не нужны, так как взаимное исключение обеспечи
вает select; сигналы не нужны благодаря проверке перед accept (рандеву вида «пе
редать» просто не будет обслужено, пока функция «полон» вырабатывает логи
ческое значение true). Причем эти проверки происходят в одном процессе буф,
никаких проблем с прерываниями при таких проверках нет.
Таким образом, мы получили то, к чему стремились, – асимметричное ранде
ву может служить универсальным и надежным средством программирования па
раллельных процессов.
Вопрос. Зачем нужна альтернатива с задержкой?
Подсказка. Если нельзя выбрать ни одной альтернативы при операторе отбора, то
возникает исключительная ситуация.
Современное состояние языков программирования
6.11. Управление асинхронными
процессами в Аде
Рассмотрим (частично уже известные) сведения об асимметричном рандеву
в рамках его воплощения в Аде.
Кроме основного примитиварандеву, в ЯП нужен аппарат управления ранде
ву (сравните операторы «оградить», «освободить», «послать», «ждать» для ранее
рассмотренных примитивов). В Аде аппарат управления рандеву состоит из
ОБЪЯВЛЕНИЯ ВХОДА (entry), ОПЕРАТОРА ВЫЗОВА ВХОДА (синтакси
чески не отличимого от вызова процедуры), оператора ПРИЕМА (accept), опера
тора ОТБОРА ВХОДОВ (select) и некоторых других.
Подчеркнем, что процедуры в Аде все считаются повторновходимыми (к ним
можно независимо обращаться из различных асинхронных процессов, и их тела
могут одновременно исполняться в этих процессах). Входы отличаются от проце
дур, вопервых, тем, что обращения к ним из различных процессов выполняются
строго в порядке очереди (именно здесь встроено взаимное исключение процессов
конкурентов), вовторых, наличием не одного, а многих «тел» – операторов при
ема, расположенных и исполняемых в различных точках процессамастера.
Оператор ЗАДЕРЖКИ (delay) приостанавливает исполнение задачи, в ко
торой он находится, на указанный в нем период (реального, астрономического)
времени.
Вызов ВХОДА R, находящийся в задаче К, аналогичен вызову процедуры, но
в общем случае не исполняется немедленно, а лишь «заказывает РАНДЕВУ» ка
тегории R. Это значит, что задача К (клиент по входу R) готова к рандеву с другой
задачеймастером М, в которой вход R объявлен. Она оказывается готовой обслу
жить заказ задачи К лишь тогда, когда достигнет оператора ПРИЕМА (accept)

Асинхронные процессы
173
входа R. Оператор приема предписывает действия, выполняемые в момент ранде
ву. Когда эти действия завершаются, рандеву считается состоявшимся, и обе зада
чи могут продолжать асинхронно работать (до следующего взаимодействияран
деву). Если задача М достигает оператора приема входа R раньше, чем его закажет
какаялибо обслуживаемая задача, то задача М приостанавливается и ждет появ
ления заказов (ждет рандеву).
Таким образом, рандеву происходит тогда (и только тогда), когда и клиент,
и мастер оказываются к нему готовыми (задача К дошла до вызова входа и заказа
ла рандеву категории R, а задача М дошла до оператора приема и готова выпол
нить заказ).
Собственно рандеву состоит в том, что аргументы вызова входа R (из задачи
клиента) связываются с параметрами оператора приема (из задачимастера) и
выполняется тело оператора приема.
Все происходит так, как будто из задачи К обращаются к процедуре R, объяв
ленной в задаче М. Выполнение оператора приема в задаче М означает тем самым
и выполнение оператора вызова в задаче К (и тем самым завершение рандеву ка
тегории R). Другими словами, задачи К и М как бы сливаются на время рандеву,
а затем продолжают работать независимо до следующего возможного рандеву.
Оператор ОТБОРА ВХОДОВ (select) позволяет мастеру ожидать сразу не
скольких рандеву и отбирать (из заказанных!) те рандеву, которые удовлетворя
ют указанным в этом операторе УСЛОВИЯМ ОТБОРА.
Формально спецификация задачи – это объявление объекта анонимного за
дачного типа. Оно связывает имя задачи с объектом, который представляет асин
хронный процесс, определяемый телом соответствующей задачи. Таким образом,
данные задачных типов – активные данные. Объект задачного типа, то есть асин
хронный процесс, запускается (начинает работать) в момент, когда заканчивается
обработка объявления объекта (в нашем случае – объявления задачи).
В языке Ада можно объявить именованный задачный тип. Например:
task type анализ is
entry прими(X: in сообщение );
end анализ;
Такое объявление связывает имя «анализ» с задачным типом, класс значений
которого – асинхронные процессы с входом «прими», определяемые телом задачи
с именем «анализ».
В контексте, где доступен задачный тип «анализ», можно объявить индивиду
альную задачу этого типа, например:
А: анализ; – то есть обычное объявление объекта.
При обработке такого объявления запускается новый асинхронный процесс
типа «анализ» (то есть создается новый объект задачного типа «анализ»), и с ним
связывается имя А. Если нужно, можно запустить и другие процессы этого типа
объявлениями
А1: анализ;
А2: анализ; – и т. д.

174
Современное состояние языков программирования
При этом доступ к входу «прими» нужного процесса обеспечивает составное
имя вида А1.прими, А2.прими и т. п.
Когда же имеется единственный процесс с входом «прими», имя задачи можно
не указывать и пользоваться простым именем входа.
Обратите внимание, что входы задач можно рассматривать как аналоги селек
торов в объектах комбинированных типов. Обращение к входу по составному
имени напоминает выборку значений поля. В определяющем пакете для задачно
го типа могут быть объявлены подходящие базовые операции. Все сказанное и
позволяет считать задачные типы полноценными (ограниченными!) типами дан
ных, причем данных активных, а не пассивных.
Объекты задачных типов могут служить компонентами объектов составных
типов. Например, можно объявить массив из десяти анализаторов:
A: array (1..10) of анализ;
и обращаться к соответствующим входам с помощью индексации
А(1).прими ...; ...; А(10).прими ...
Задачные объекты могут, естественно, быть и динамическими. Например,
можно ввести ссылочный тип
type Р is access анализ;
и переменную R типа Р
R : Ð;
Теперь понятно действие оператора
R := new анализ;
А именно создается новый асинхронный процесс типа «анализ» и ссылка на
него помещается в R. К соответствующему входу можно теперь обращаться через
R.прими ...
Подчеркнем, что у динамических задачных объектов не может быть динами
ческих параметров, так что все сказанное про соответствие задачных типов кон
цепции уникальности сохраняет силу и для динамических задачных объектов.
Формально тело задачи отличается от тела процедуры лишь тем, что в первом
допустимы специальные «задачные» операторы, недопустимые в теле обычной
процедуры.
Как уже сказано, рациональной структуризацией управления асинхронными
процессами много и плодотворно занимался БринчХансен. Интересующегося
читателя отсылаем к [13]. Практическим результатом исследований проблем па
раллелизма еще одним классиком информатики Тони Хоаром стал язык парал
лельного программирования Оккам. Ему (точнее, его последней версии Оккам2)
посвящен специальный раздел.

Нотация
7.1. Проблема знака в ЯП .............. 176
7.2. Определяющая
потребность .................................. 176
7.3. Основная абстракция.............. 177
7.4. Проблема конкретизации
эталонного текста.......................... 177
7.5. Стандартизация алфавита ...... 178
7.6. Основное подмножество
алфавита ....................................... 179
7.7. Алфавит языка Ада.................. 179
7.8. Лексемы ................................. 180
7.9. Лексемы в Аде ........................ 181
Глава 7

176
Современное состояние языков программирования
7.1. Проблема знака в ЯП
Вспомним, что ЯП – знаковая система. Но знаковая ситуация возникает лишь
тогда, когда знак может быть передан отправителем и получен адресатом. Как от
правителем, так и адресатом может оказаться и человек, и компьютер.
ЯП должен быть средством мышления людей, создающих программы; сред
ством их общения между собой по поводу создания программ; средством общения
людей с компьютерами и, наконец, компьютеров между собой.
Для людей важно, чтобы знаки были и выразительны, и надежны, и лаконич
ны, и удобны для письма и чтения. Необходимость общаться с компьютерами
предъявляет к знакам особые требования. Достаточно вспомнить, что знаки ЯП
нужно вводить устройствами ввода и выводить устройствами вывода. К тому же
они должны восприниматься имеющейся в распоряжении программной средой.
Указанные требования весьма разнообразны и порой противоречивы. При
вычных людям знаков часто нет на устройствах вводавывода. Может оказаться
невозможным использовать буквы кириллицы, некоторые привычные символы
операций, опускать и поднимать индексы и т. п. Обычно невозможно вводить ру
кописный текст (хотя в будущем это наверняка станет возможным).
Итак, даже если в знаковой ситуации, соответствующей ЯП, сконцентриро
вать внимание исключительно на выборе знаков, по возможности абстрагируясь
от проблемы смысла, то найти решение, удовлетворяющее в разумной мере
пользователей ЯП и производителей оборудования, бывает очень не просто. Ког
да же необходимо искать решение с учетом массового применения ЯП в нацио
нальном (тем более мировом) масштабе, то возникает самостоятельная серьезная
проблема – проблема знака.
В этом разделе мы сконцентрируемся лишь на части этой большой проблемы –
проблеме представления знаков (проблеме нотации).
7.2. Определяющая потребность
Выделим технологическую потребность, определяющую в настоящее время реше
ние проблемы нотации, – потребность записывать программу так, чтобы ее можно
было ввести в любой компьютер без особых затрат и риска внести ошибки. Назовем
ее потребностью совместимости по вводу. Эта потребность – определяющая в том
смысле, что ради ее удовлетворения в современной ситуации с индустриальным
программированием можно в значительной степени пренебречь, например, поже
ланиями некоторых категорий пользователей (разнообразие шрифтов, управле
ние цветом, нелинейная запись и т. п.).
Другими словами, пишущий программу (отправитель знака) должен иметь
возможность абстрагироваться от особенностей устройств ввода у адресата.
С другой стороны, нужно обеспечить возможность «каждому желающему» конк
ретному исполнителю выступить в роли адресата, возможность воспринять напи
санное отправителем.

Нотация
177
7.3. Основная абстракция
Абстракция, обслуживающая потребность совместимости по вводу, хорошо изве
стна – это абстрактный (эталонный) текст. Понятие эталонного текста определе
но в каждом ЯП. Эталонный текст – это конечная последовательность эталонных
символов. Набор символов в ЯП обычно конечен и линейно упорядочен. Он назы
вается алфавитом ЯП. Потребность в совместимости удовлетворяется за счет
того, что на определенном уровне абстракции именно эталонный текст является
знаком программы. Именно он подразумевается, когда работают на конкретном
устройстве вводавывода.
Но на конкретном устройстве свой алфавит. Так что приходится придумывать
способ обозначать эталонные символы конкретными символами, доступными на
устройстве, а эталонный текст в целом – конкретным текстом (составленным из
конкретных символов). Так, эталонные символы Алгола60 (begin, end и т. п.) обо
значаются иногда "BEGIN", "END", иногда _begin_ , _end_ , иногда 'НАЧАЛО',
'КОНЕЦ' и т. п.
Таким образом, конкретный текст обозначает эталонный, а тот, в свою очередь,
обозначает программу.
Итак, основная абстракция осознана – это эталонный текст. Но в соответствии
с принципом реальности абстракций для каждой абстракции нужны средства
конкретизации. Проблема нотации дает пример, когда средства конкретизации по
необходимости выходят за рамки языка, создавая внешнюю проблему конкрети
зации эталонного текста.
7.4. Проблема конкретизации
эталонного текста
Обычно в ЯП отсутствуют средства управления связью конкретных и абстракт
ных текстов. Дело в том, что средства управления сами должны быть обозначены
некоторыми текстами, их также нужно вводить и выводить. Короче, для них воз
никнут те же проблемы, что и для ЯП в целом. Так что решать проблему конкре
тизации приходится вне ЯП.
Тем более важно принять рациональные решения, определяющие правила
конкретизации абстрактных текстов, так как они принимаются «раз и навсегда».
Важность решений, о которых идет речь, можно показать на классическом
примере Алгола60. В свое время его авторы по существу игнорировали проблему
конкретизации. Они ввели три уровня языка – эталонный, для публикаций и кон
кретные представления. Первый был ориентирован «исключительно на взаимо
понимание», второй – на «типографские особенности», третий – на устройства
вводавывода. Что касается проблемы конкретизации, то авторы ограничились
оговоркой, что каждая реализация должна иметь «правила для перевода конкрет
ных представлений в эталонные».

178
Именно «правила», а не программы и не программные изделия для перевода!
Затраты ресурсов на такой перевод и риск внести ошибки не оценивались и не
контролировались. На практике это привело к несовместимости различных
трансляторов с Алгола60. Так как реализаторы не только не подкрепляли «пра
вила» конкретными программными изделиями, но и не всегда четко осознавали
«правила». Проблема несовместимости реализаций, в свою очередь, сыграла не
последнюю роль в том, что Алгол60 не сумел выдержать конкуренцию с Фортра
ном в качестве языка массового программирования для научных расчетов.
Итак, допустим, что важность проблемы конкретизации осознана. Как рацио
нально решить эту проблему?
Современное состояние языков программирования
7.5. Стандартизация алфавита
Игнорировать проблему нельзя, управлять конкретизацией невозможно. Остает
ся по существу единственный путь – стандартизация алфавита (или определение
ЯП со стандартным алфавитом).
Ключевая идея состоит в том, что проблема выносится за рамки рассматривае
мого ЯП и выбирается опорный стандарт на цифровые коды символов (достаточно
распространенный, лучше всего – международный). Эталонный алфавит ЯП опре
деляется через опорный стандарт (по существу, эталонным алфавитом становится
некоторое подмножество цифровых кодов символов из опорного стандарта, а свя
занные с этими кодами видимые (графические) и (или) управляющие символы об
разуют допустимые конкретные алфавиты). Тем самым определяются и допусти
мые вариации конкретных алфавитов (рамками того же опорного стандарта).
С одной стороны, авторы ЯП вынуждены выбирать из стандартного набора
символов. С другой стороны, производители оборудования и систем программи
рования вынуждены считаться с действующими стандартами и обеспечивать, во
первых, наличие на клавиатуре устройств минимального набора знаков и, вовто
рых, их правильное, определяемое стандартом соответствие цифровым кодам
(например, А – 101, В – 102, 0 (нуль) – 60, 1 – 61 в коде ASCII и т. п.). Таким
образом, на некотором этапе обработки текст обязательно представлен стандарт
ной последовательностью числовых кодов. Ее и следует считать эталонным тек
стом. Именно такой эталонный текст обеспечивает практическую совместимость
по вводу.
Стандартизация алфавита требует коллективных усилий международного со
общества, самоограничения и дисциплины авторов ЯП, производителей компью
теров и периферийных устройств. Но зато и уровень совместимости по вводу
в ЯП со стандартизированным алфавитом зависит не от распространенности конк
ретной реализации языка, а от распространенности опорного стандарта.
Благодаря целенаправленной деятельности национальных и международных
организаций по стандартизации в настоящее время существуют достаточно авто
ритетные стандарты на символы (7 и 8битовый Международные стандарты
ИСО и соответствующие национальные стандарты, в том числе и отечественный

Нотация
ГОСТ). Так что создана приемлемая база для разработки ЯП со стандартным
алфавитом.
Рост технических возможностей и соответственно потребностей пользовате
лей может привести к пересмотру стандартов на коды символов (например, чтобы
можно было работать с цветом или с различными шрифтами). Тогда появится
больше возможностей и у авторов ЯП. Вместе с тем потери от несовместимости
обычно несопоставимы с выигрышем от нарушения стандарта, так что известная
доля консерватизма в решении проблемы нотации вполне естественна.
Для ЯП со стандартным алфавитом нет особого смысла различать эталонные и
конкретные тексты. Другими словами, абстракция представления в этом случае
почти вырождается в результате стандартизации конкретных представлений.
Первым ЯП со стандартным алфавитом был Фортран. В настоящее время этот
путь решения проблемы представления знака для вновь создаваемых ЯП можно
считать общепринятым.
179
7.6. Основное подмножество алфавита
Еще одна заслуживающая внимания идея (позволяющая работать на «бедных»
устройствах, не соответствующих полному опорному стандарту на коды симво
лов) состоит в выделении так называемого основного подмножества алфавита.
При этом в определении ЯП фиксируются правила изображения остальных сим
волов алфавита с помощью комбинаций символов из основного подмножества.
Написанный по этим правилам текст обозначает нужный текст в полном алфави
те, а передавать и воспринимать его можно на «бедных» устройствах.
В любой «богатой» реализации ЯП можно (и нужно) иметь средства для коди
рования и декодирования «бедных» текстов по упомянутым правилам, так что
идея основного подмножества практически не мешает «богатым» пользователям
и существенно помогает «бедным».
7.7. Алфавит языка Ада
Текст исходной программы в Аде – это последовательность символов. Символы
делятся на графические и управляющие. Каждому символу однозначно соответ
ствует 7битовый код ИСО. Вариации графических символов возможны только
в рамках, допустимых стандартом ИСО для национальных стандартов (например,
знак доллара можно заменить знаком фунта стерлингов). Управляющие символы
графического представления не имеют, они предназначены для форматирования
текста (горизонтальная табуляция, вертикальная табуляция, возврат каретки, пе
ревод строки, перевод страницы).
Среди графических символов выделено основное множество (прописные ла
тинские буквы, цифры, пробел и специальные символы # &’()* + ,– .:;<=>_|.
Кроме того, в алфавит входят строчные латинские буквы и дополнительные
символы (! $ % ? @ [ \ ] ' '{}^).

180
Правила, позволяющие обозначить произвольную программу с помощью толь
ко основного множества, таковы. Вопервых, в качестве обязательных элементов
программы (ключевые слова, ограничители и разделители) используются только
символы из основного множества. Вовторых, строчные и прописные буквы эквива
лентны всюду, кроме строк и символьных констант. (Так что и идентификаторы
можно представлять в основном множестве.) А строки обозначаются с помощью
символа & так, что «явное» изображение строки эквивалентно «косвенному», ис
пользующему название нужной подстроки. Например, если ASCII.DOLLAR –
это название строки «$», то обозначение «А $ С» эквивалентно «А» &
ASCII.DOLLAR & «С».
Подобные названия для всех дополнительных символов и строчных латинс
ких букв предопределены в языке Ада. Это и позволяет записать любую програм
му с помощью одного только основного множества. (Еще пример: «АвС» эквива
лентно «А» & ASCII.LC_B & «С»; здесь LC служит сокращением от английского
LOWER_CASE_LETTER – строчные буквы).
Современное состояние языков программирования
7.8. Лексемы
Понятие эталонного текста как последовательности символов (литер) позволяет
абстрагироваться от особенностей устройств вводавывода. Однако символ –
слишком мелкая единица с точки зрения тех сущностей, которые необходимо обо
значать в ЯП. Их намного больше, чем элементов в алфавите. Удобно, когда эти
сущности имеют индивидуальные обозначения, подобные словам естественного
языка, а текст оказывается последовательностью таких «слов», называемых лек
семами. Мы пришли к еще одному (промежуточному) уровню абстракции – уров
ню лексем. (Можно считать, что этот уровень удовлетворяет потребность в раци
ональной микроструктуре текста – приближает размеры «неделимого» знака
к размеру «неделимого» денотата.)
Когда этот уровень абстракции выделен явно, и при письме, и при чтении мож
но оперировать достаточно крупными единицами (лексемами), абстрагируясь
(когда это нужно) от конкретного способа представления лексем символами ал
фавита. Становится проще манипулировать с текстом, увеличивается надеж
ность, растет скорость создания и восприятия текста.
Между тем в ЯП уровень лексем выделяется далеко не всегда. Неудачная идея
игнорировать пробелы как естественные разделители возникла на заре развития
ЯП (сравните Фортран и Алгол60), повидимому, как отрицательная реакция на
необходимость «считать пробелы» в первых позиционных автокодах. В результа
те была временно утеряна отлично зарекомендовавшая себя традиция естест
венных языков – выделять слова пробелами. В Алголе60 к тому же игнорируют
ся все управляющие символы, а в Фортране – переход на новую строку внутри
оператора. В естественных языках подобные особенности текста обычно исполь
зуются как разделители слов. В последние годы идея явного выделения уровня
лексем становится общепризнанной и при конструировании ЯП.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
