> if( N
> 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реды. Для таких приложений вполне достаточно использования функций