Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Языки программирования. Практический сравнитель...doc
Скачиваний:
31
Добавлен:
09.09.2019
Размер:
2.68 Mб
Скачать

12.6. Язык параллельного программирования оссаm

Модель синхронных сообщений была первоначально разработана Хоаром (С. A. R. Ноаге) в формализме, называющемся CSP (Communicating Sequential Processes — Взаимодействующие последовательные процессы). На практике он реализован в языке оссат, который был разработан для про­граммирования транспьютеров — аппаратной многопроцессорной архитек­туры для распределенной обработки данных.

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

CHAN OF INT с :

PAR

INT m:

SEQ

-- Создается целочисленное значение m

с! m

INT v:

SEQ

c? v

-- Используется целочисленное значение в v

с объявлено как канал, который может передавать целые числа. Канал дол­жен использоваться именно в двух процессах: один процесс содержит коман­ды вывода (с!), а другой — команды ввода (с?).

Интересен синтаксис языка оссаm. В других языках режим выполнения «по умолчанию» — это последовательное выполнение группы операторов, а для задания параллелизма требуются специальные указания. В языке оссаm парал­лельные и последовательные вычисления считаются в равной степени важ­ными, поэтому вы должны явно указать, используя PAR и SEQ, как именно должна выполняться каждая группа (выровненных отступами) операторов.

Хотя каждый канал связывает ровно два процесса, язык оссаm допускает, чтобы процесс одновременно ждал передачи данных по любому из несколь­ких каналов:

[10]CHAN OF INT с : -- Массив каналов

ALT i = O FOR 10

c[i] ? v

-- Используется целочисленное значение в v

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

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

12.7. Рандеву в языке Ada

Задачи в языке Ada взаимодействуют друг с другом во время рандеву (ren­dezvous). Говорят, что одна задача Т1 вызывает вход (entry) e в другой задаче Т2 (см. рис. 12.3). Вызываемая задача должна выполнить accept-оператор для этого входа:

accept Е(Р1: in Integer; P2: out Integer) do

end E;

Когда задача выполняет вызов входа, и есть другая задача, которая уже вы­полнила accept для этого входа, имеет место рандеву.

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

• Принимающая задача выполняет операторы в теле accept.

• Принимающая задача возвращает выходные параметры вызывающей задаче.

• Вызывающая задача разблокируется.

Определение рандеву симметрично в том смысле, что, если задача выпол­няет accept-оператор, но ожидаемого вызова входа еще не произошло, она

будет заблокирована, пока некоторая задача не вызывет вход для этого accept-оператора*.

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

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

Механизм рандеву чрезвычайно сложен: задача может одновременно ждать вызова различных точек входа, используя select-оператор:

select

accept El do ... end El;

or

accept E2 do . . . end E2;

or

accept E3 do . . . end E3;

end select;

Альтернативы выбора в select могут содержать булевы выражения, назы­ваемые охраной (guards), которые дают возможность задаче контролировать, какие вызовы она хочет принимать. Можно задавать таймауты (предельные времена ожидания рандеву) и осуществлять опросы (для немедленной реакции в критических случаях). В отличие от конструкции ALT в языке оссаm, select-оператор языка Ada не может одновременно ожидать произ­вольного числа входов.

Обратите внимание на основное различие между защищенными перемен­ными и рандеву:

• Защищенная переменная — это пассивный механизм, а его операции выполняются другими задачами.

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

Рандеву можно использовать для программирования сервера и в том случае, если сервер делает значимую обработку помимо связи с клиентом:

task Server is

begin

loop

select

accept Put(l: in Item) do

-- Отправить I в структуру данных

end Put;

or

accept Get(l: out Item) do

-- Достать I из структуры данных

end Get;

end select;

-- Обслуживание структуры данных

end loop;

end Server;

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

В языке Ada чрезвычайно гибкий механизм параллелизма, но эта гибкость достигается ценой менее эффективной связи, чем коммуникации точка-точка в языке оссаm. С другой стороны, в языке оссаm фактически невоз­можно реализовать гибкий серверный процесс, так как каждый дополни­тельный клиентский процесс нуждается в отдельном именованном канале, а это требует изменения программы сервера.

12.8. Linda

Linda — это не язык программирования как таковой, а модель параллелизма, которая может быть добавлена к существующему языку программирования. В отличие от однонаправленной (Ada) или двунаправленной адресации (occam), Linda вообще не использует никакой адресации между параллель­ными процессами! Вместо этого процесс может по выбору отправить сооб­щение в глобальную кортежную область (Tuple Space). Она названа так пото­му, что каждое сообщение представляет собой кортеж, т. е. последователь­ность из одного или нескольких значений, возможно, разных типов.

Например:

(True, 5.6, 'С', False)

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

Существуют три операции, которые обращаются к кортежной области:

out — поместить кортеж в кортежную область;

in — блокировка, пока не существует соответствующего кортежа, затем его удаление

(см. рис. 12.4);

read — блокировка, пока не существует соответствующего кортежа (но без удаления его).

Синхронизация достигается благодаря тому, что команды in и read должны определять сигнатуру кортежа: число элементов и их типы. Только если кор­теж существует с соответствующей сигнатурой, может быть выполнена опе­рация получения, иначе процесс будет приостановлен. Кроме того, один или несколько элементов кортежа могут быть заданы явно. Если значение задано в сигнатуре, оно должно соответствовать значению в той же самой позиции кортежа; если задан тип, он может соответствовать любому значению этого типа в данной позиции. Например, все последующие операторы удалят пер­вый кортеж в кортежной области на рис. 12.4:

in(True, 5.6, 'С', False)

in(B: Boolean, 5.6, 'С', False)

in(True, F: Float, 'С', Ё2: Boolean)

Второй оператор in возвратит значение True в формальном параметре В; тре­тий оператор in возвратит значения 5.6 в F и False — в В2.

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

in("job", J: Jobs, 4); -- Компьютер 4 ждет работу

Задача диспетчеризации может «бросать» работы в кортежную область. С по­мощью формального параметра оператора out можно указать, что безразлич­но, какой именно компьютер делает данную работу:

out("job", 6, С: Computers); -- Работа 6 для любого компьютера

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

только позднее другой процесс найдет этот кортеж. Таким образом, Linda-программа распределена как во времени, так и в пространстве (среди процес-сов, которые могут быть на отдельных ЦП). Сравните это с языками Ada и oссаm, которые требуют, чтобы процессы непосредственно связывались друг с другом. Недостаток модели Linda состоит в дополнительных затратах на поддержку кортежной области, которая требует потенциально неограничен­ной глобальной памяти. Хотя кортежная область и является глобальной, бы-ли разработаны сложные алгоритмы для ее распределения среди многих про­цессоров.