// 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-очередей.
Объектно-ориентированные каналы и FIFO-очереди как базовые элементы низкого уровня
Приступая к разработке объектноориентированных каналов, начнем с рассмотрения базовых характеристик и поведения каналов в целом. Канал представляет собой средство взаимодействия между несколькими процессами. Для того чтобы процессы могли взаимодействовать, необходимо обеспечить между ними передачу информации определенного вида. Эта информация может представлять данные или команды, предназначенные для выполнения. Обычно такая информация преобразуется в последовательность данных и помещается в канал, а затем считывается процессом с другого конца канала. При считывании из канала данные снова преобразуются, чтобы обрести смысл для считывающего процесса. В любом случае при передаче от одного процесса другому эти данные должны где-то храниться. Мы называем область хранения информации буфером данных. Для размещения данных в этом буфере и извлечения их оттуда необходимо выполнять соответствующие операции. Но прежде чем говорить о выполнении таких операций, необходимо позаботиться о существовании самого буфера данных. Объектно-ориентированный канал должен обладать средствами, которые поддерживают операции создания и инициализации буфера данных. После завершения взаимодействия между процессами буфер данных, используемый для хранения информации, становится ненужным. Это означает, что наш объектно-ориентированный канал должен «уметь» удалять буфер данных после его использования. Из этого «введения в каналы» вырисовываются по крайней мере пять основных компонентов, которыми должен обладать объектно-ориентированный канал:
• буфер;
• операция вставки данных в буфер;
• операция извлечения данных из буфера;
• операция создания/инициализации буфера;
• операция ликвидации буфера.
Помимо этих пяти базовых компонентов, канал должен иметь два конца. Один конец предназначен для вставки данных, а другой — для их извлечения. К этим двум концам могут получать доступ различные процессы. Чтобы наше описание канала было полным, мы должны включить в него порт ввода и порт вывода, к которым могут подключаться различные процессы. В результате мы получаем уже семь базовых компонентов, составляющих описание нашего объектно-ориентированного канала:
• порт ввода;
• порт вывода;
• буфер;
• операция вставки данных в буфер;
• операция извлечения данных из буфера;
• операция соз
• операция ликви