Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 301

Сами элементы отправляются с использованием одного из стандартных С++-алгоритмов:

copy(X.begin() ,X.end() ,OPtr) ;

Алгоритм copy () копирует содержимое одного контейнера в контейнер, связанный с итератором приемника. Здесь итератором приемника является объект OPtr. Объект OPtr связан с объектом OPipe, поэтому при выполнении алгоритма copy () («уместившегося» в одной строке кода) в канал переписывается все содержимое контейнера. Этот пример демонстрирует возможность использования стандартных алгоритмов для организации взаимодействия между различными частями сред параллельного или распределенного программирования. В данном случае алгоритм copy () пересылает информацию от одного процесса другому (из одного адресного пространства в другое). Эти процессы выполняются параллельно, и алгоритм copy () значительно упрощает взаимодействие между ними. Мы подчеркиваем важность этого подхода, поскольку, если есть хоть какал-то возможность упростить логику параллельной или распределенной программы, ею нужно непременно воспользоваться. Ведь межпроцессное взаимодействие — это один из самых сложных разделов параллельного или распределенного программирования. С++-алгоритмы, библиотека классов iostreamS и итератор типа ostream_iterator как раз и позволяют понизить уровень сложности разработки таких программ. Использование манипулятора flush (в строке 33) гарантирует прохождение данных по каналу.

В программе 11.2.1 сыновний процесс сначала получает количество объектов, принимаемых от канала (в строке 36), а затем для считывания самих объектов использует объект IPipe класса istream.

>// Программа 11.2.1

>11 class multiplier{

>12 float X;

>13 public:

>14 multiplier(float Value) { X = Value;}

>15 float &operator()(float Y) { X = (X * Y);return(X);}

>16 }; 17

>18

>19 int main(int argc,char *argv[])

>20 {

>21 char Value[50] ;

>22 int Fd[2] ;

>23 float Data;

>24 vector X;

>25 int NumElements;

>26 multiplier N(12.2);

>27 strcpy(Value,getenv(«Fdin»));

>28 Fd[0] = atoi(Value);

>29 strcpy(Value,getenv(«Fdout»));

>30 Fd[l] = atoi(Value);

>31 ifstream IPipe;

>32 ofstream OPipe;

>33 IPipe.attach(Fd[0]) ;

>34 OPipe.attach(Fd[l]) ;

>35 ostream_iterator OPtr(OPipe,"\n»);

>36 IPipe » NumElements;

>37 for(int N = 0;N < NumElements;N++)

>38 {

>39 IPipe » Data;

>40 X.push_back(Data);

>41 }

>42 OPipe « X.size() « endl;

>43 transform(X.begin(),X.end(),OPtr,N);

>44 OPipe « flush;

>45 return(0); 46

>47 }

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