Этот вид защиты позволяет сделать класс pvm_stream безопасным. Здесь мы не представили код обработки исключений или другой код, который бы позволил предотвратить бесконечные отсрочки или взаимную блокировку. Основнал идея в данном случае — сделать акцент на компонентах и вариантах архитектуры, которые пригодны для поддержки параллелизма. Интерфейсный класс mutex и класс pvm_stream можно использовать многократно, и оба они поддерживают параллельное программирование. Предполагается, что объекты класса pvm_stream должны использоваться PVM-задачами при отправке и приеме сообщений. Но это не является жестким требованием. Для того чтобы пользователь мог применить концепцию класса pvm_stream к своим классам, для них необходимо определить операторы вставки (<<) и извлечения (>>).
Пользовательские классы, создаваемые для обработки PVM-потоков данных
Чтобы понять, как определенный пользователем класс можно использовать совместно с классом pvm_stream, попробуем усовершенствовать возможности PVM-палитры, представленной в главе 6. Класс палитры представляет простую коллекцию цветов. Для удобства будем сохранять цвета в векторе строк (vector
Начне
// Листинг 11.16. Объявление класса spectral_palette
class spectral_palette : public pvm_object{
protected:
//. . .
vector
public:
spectral_palette(void);
//...
friend pvm_stream &operator>>(pvm_stream &In,spectral_palette &Obj);
friend pvm_stream &operator<<(pvm_stream &Out,spectral_palette &Obj);
//. . .
Обратите внимание на то, что класс 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
Source.append(" ");
}
}
Out.reset();
Out.taskId(Obj.TaskId);
Out.messageId(Obj.MessageId);
Out << Source;
return(Out);
}
Рассмотрим подробнее определение этой операции вставки в листинге 11.17. Поскольку класс pvm_stream работает только со встроенными типами данных, цель пользовательского оператора "<<" — перевести пользовательский объект в последовательность значений встроенных типов данных. Этот перевод является одной из основных обязанностей классов, «отвечающих» за потоковое представление данных. В данном случае объект класса spectral_palette должен быть переведен в строку «цветов», разделенных пробелами. Список цветовых значений сохраняется в строке Source. Рассматриваемый процесс перевода позволяет применить к объекту этого класса оператор "<<", который был определен для строкового типа данных. Имея определения этих операторов, API-интерфейс программиста становится более удобным, чем при использовании ори
// Листинг 11.18. Использование объектов классов