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

.

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

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

>11 {

>12

>13 int Size,Pid,Status,Fdl[2],Fd2[2];

>14 pipe(Fdl); pipe(Fd2);

>15 strstream Buffer;

>16 char Value[50];

>17 float Data;

>18 vectorX(5,2.1221), Y;

>19 Buffer « Fdl[0] « ends;

>20 Buffer » Value;

>21 setenv(«Fdin»,Value,l);

>22 Buffer.clear();

>23 Buffer « Fd2[l] « ends;

>24 Buffer » Value;

>25 setenv(«Fdout»,Value,l);

>26 Pid = fork();

>27 if(Pid != 0){

>28 ofstream OPipe;

>29 OPipe.attach(Fdl[l] ) ,-

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

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

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

>33 OPipe « flush;

>34 ifstream IPipe;

>35 IPipe.attach(Fd2[0]);

>36 IPipe » Size;

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

>38 {

>39 IPi ре » Data;

>40 Y.push_back(Data);

>41 }

>42 wait(&Status);

>43 ostream_iterator OPtr2(cout,"\n»);

>44 copy(Y.begin(),Y.end(),OPtr2);

>45 OPipe.close();

>46 IPipe.close();

>47 }

>48 else{

>49 execl("./programll-2b»,«programll-2b»,NULL);

>50 } 51

>52 return(0);

>53 }

В строках 21 и 25 системнал функция setenv () используется для передачи значений файловых дескрипторов сыновнему процессу. Это возможно благодаря тому, что сыновний процесс наслелует среду родительского процесса. Мы можем устанавливать переменные среды в программе с помощью вызова функции setenv (). В данном случае мы устанавливаем их следующим образом.

Fdin=filedesc; Fdout=filedesc;

Сыновний процесс затем использует системный вызов getenv( ) для считывания значений переменных Fdin и Fdout. Значение переменной Fdin будет представлять «считывающий конец» канала для сыновнего процесса, а значение переменной Fdout — «записывающий». Использование системных функций setenv () и getenv() обеспечивает просгую форму межпроцессного взаимодействия (interprocess communication — IPC) между родительским и сыновним процессами. Каналы создаются при выполнении инструкций, приведенных в строке 14. Родительский процесс присоединяется к одному концу канала для операции записи с помощью метода attach() (строка29). После присоединения любые данные, помещенные в объект OPipe типа ofstream, будут записаны в канал. Итератор типа ostream_iterator подключается к объекгу OPipe при выполнении следующей инструкции (строка 30):

ostream_iterator OPtr(OPipe,"\n»);

Теперь итератор OPtr ссылается на объект OPipe. После каждой порции помещаемых в канал данных будет вставляться разделитель "\n». С помощью итератора OPtr мы можем поместить в канал любое количество float -значений. При этом мы можем связать с каналом несколько итераторов различных типов. Но в этом случае необходимо, чтобы на «считывающем» конце канала данные извлекались с использованием ите раторов соответствующих типов. При выполнении слелующей инструкции из программы 11.2 в канал сначала помещается количество элементов, подлежащих передаче: