Рейтинговые книги
Читем онлайн Параллельное и распределенное программирование на С++ - Хьюз Камерон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 109 110 111 112 113 114 115 116 117 ... 181

//. . .

Обратите внимание на то, что класс spectral_palette в листинге 11.16 наследует класс pvm_object. Класс pvm_object тем самым обеспечивает своего наследника доступом к идентификатору задачи и идентификатору сообщения. Вспомните, что идентификаторы задачи и сообщения используются во многих PVM-функциях. С помощью определения операторов вставки (<<) и извлечения (>>) объекты класса spectral_palette можно пересылать между параллельно выполняемыми PVM-задачами. Метод, используемый для класса spectral_palette, очень прост, и его можно так же успешно применить к любому пользовательскому классу. Поскольку класс pvm_stream должен иметь эти операторы для встроенных типов данных и контейнеров, которые содержат значения встроенных типов данных, в пользовательском классе необходимо определить только операторы "<<" и ">>" для перевода их представления в любой встроенный тип данных или стандартный контейнер. Вот как, например, определяется оператор "<<" для класса spectral_palette в листинге 11.17.

// Листинг 11.17. Определение оператора для

// класса spectral_palette

pvm_stream &operator<<(pvm_stream &Out, spectral_palette &Obj)

{

int N;

string Source;

for(N = 0;N < Obj.Colors.size();N++) {

Source.append(Obj.Colors[N]);

if( N <Obj.Colors.size() - 1){

Source.append(" ");

}

}

Out.reset();

Out.taskId(Obj.TaskId);

Out.messageId(Obj.MessageId);

Out << Source;

return(Out);

}

Рассмотрим подробнее определение этой операции вставки в листинге 11.17. Поскольку класс pvm_stream работает только со встроенными типами данных, цель пользовательского оператора "<<" — перевести пользовательский объект в последовательность значений встроенных типов данных. Этот перевод является одной из основных обязанностей классов, «отвечающих» за потоковое представление данных. В данном случае объект класса spectral_palette должен быть переведен в строку «цветов», разделенных пробелами. Список цветовых значений сохраняется в строке Source. Рассматриваемый процесс перевода позволяет применить к объекту этого класса оператор "<<", который был определен для строкового типа данных. Имея определения этих операторов, API-интерфейс программиста становится более удобным, чем при использовании ори г инальных версий функций библиотеки Pthread, POSIX и MPI. Ведь теперь объект класса spectral_palette можно переслать из одной PVM-задачи в другую, используя такую привычную операцию вставки (<<).

// Листинг 11.18. Использование объектов классов

// pvm_stream и spectral_palette

pvm_stream TaskStream;

spectral_palette MyColors;

//. . .

TaskStream.taskId(20001);

TaskStream.messageId(l); //.. .

TaskStream « MyColors; //.. .

Здесь объект MyColors пересылается в соответствующую PVM-задачу. На рис. 11.6 показаны компоненты, используемые для поддержки объектов TaskStream и MyColors. Каждый компонент на рис. 11.6 можно детализировать и оптимизировать в отдельности. Каждый представленный здесь уровень обеспечивает дополнительный слой изоляции от сложности этих компонентов. В идеале на самом высоком уровне программист должен заниматься только деталями, связанными с данной предметной областью. Такой высокий уровень абстракции позволяет программисту самым естественным образом представлять параллелизм, который вытекает из требований предметной области, не углубляясь при этом в синтаксис и сложные последовательности вызовов функций. Компоненты, представленные на рис. 11.6, следует рассматривать лишь как малую толику библиотеки классов, которую можно использовать для PVM-программ и многопоточных PVM-программ. Те же методы можно применять для взаимодействия между параллельно выполняемыми задачами, которые не являются частью PVM-среды. Ведь существует множество приложений, которые требуют реализации параллельности, но не нуждаются во всей полноте функционирования механизма PVM-cреды. Для таких приложений вполне достаточно использования функций ехес( ), fork () или pvm_spawn (). Примерами таких приложений могут служить программы, которые требуют создания нескольких параллельно выполняемых процессов, и приложения типа «клиент-сервер». Для таких нePVM - или неМРI-приложений также может потребоваться организация межпроцессного взаимодействия. Для параллельно выполняемых процессов, создаваемых посредством fork-exec- последовательности вызовов или функций pvm_spawn, имело бы смысл поддерживать потоковое представление данных. Понятие объектно-ориентированного потока данных можно также расширить с помощью каналов и FIFO-очередей.

Рис.11.6. Компоненты, используемые для поддержки объектов TaskStream и MyColors

Объектно-ориентированные каналы и FIFO-очереди как базовые элементы низкого уровня

Приступая к разработке объектноориентированных каналов, начнем с рассмотрения базовых характеристик и поведения каналов в целом. Канал представляет собой средство взаимодействия между несколькими процессами. Для того чтобы процессы могли взаимодействовать, необходимо обеспечить между ними передачу информации определенного вида. Эта информация может представлять данные или команды, предназначенные для выполнения. Обычно такая информация преобразуется в последовательность данных и помещается в канал, а затем считывается процессом с другого конца канала. При считывании из канала данные снова преобразуются, чтобы обрести смысл для считывающего процесса. В любом случае при передаче от одного процесса другому эти данные должны где-то храниться. Мы называем область хранения информации буфером данных. Для размещения данных в этом буфере и извлечения их оттуда необходимо выполнять соответствующие операции. Но прежде чем говорить о выполнении таких операций, необходимо позаботиться о существовании самого буфера данных. Объектно-ориентированный канал должен обладать средствами, которые поддерживают операции создания и инициализации буфера данных. После завершения взаимодействия между процессами буфер данных, используемый для хранения информации, становится ненужным. Это означает, что наш объектно-ориентированный канал должен «уметь» удалять буфер данных после его использования. Из этого «введения в каналы» вырисовываются по крайней мере пять основных компонентов, которыми должен обладать объектно-ориентированный канал:

• буфер;

• операция вставки данных в буфер;

• операция извлечения данных из буфера;

• операция создания/инициализации буфера;

• операция ликвидации буфера.

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

• порт ввода;

• порт вывода;

• буфер;

• операция вставки данных в буфер;

• операция извлечения данных из буфера;

• операция соз д ания/инициализации буфера;

• операция ликви д ации буфера.

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

1 ... 109 110 111 112 113 114 115 116 117 ... 181
На этой странице вы можете бесплатно читать книгу Параллельное и распределенное программирование на С++ - Хьюз Камерон бесплатно.
Похожие на Параллельное и распределенное программирование на С++ - Хьюз Камерон книги

Оставить комментарий