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

// Программа 11.1

1   #include

2   #include

3   #include

4   #include

5   #include 6

7 8 9

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

11   {

12

13   int Fd[2];

14   int Pid;

15   float Value;

16   int Status;

17   if(pipe(Fd) != 0) {

18   cerr « «Ошибка при создании канала " « endl;

19   exit(l);

20   }

21   Pid = fork();

22   if(Pid == 0){

23   ifstream IPipe(Fd[0]);

24   IPipe » Value;

25   cout « «От процесса-родителя получено значение» << Value << endl;

26   IPipe.close();

27   }

28   else{

29   ofstream OPipe(Fd[l]);

30   OPipe « M_PI « endl;

31   wait(&Status);

32   OPipe.close();

33

34 }

35

36 }

Вспомните, что значение 0, возвращаемое функцией fork(), принадлежит сыновнему процессу. В программе 11.1 канал создается при выполнении инструкции, расположенной на строке 17. А при выполнении инструкции, расположенной на строке 29, родительский процесс открывает канал для записи. Файловый дескриптор Fd[1] означает «записывающий» конец канала. К этому концу канала (благо д аря вызову конструктора на строке 29) присоединяется объект класса ofstream. К «считывающему» концу канала присоединяется объект класса ifstream (строка 23). Сыновний процесс открывает канал для чтения и получает доступ к дескриптору файла, поскольку он вместе со средой родителя наслелует и дескрипторы файлов. Таким образом, любые файлы, которые открыты в среде родителя, будут оставаться открытыми и в среде наследника, если операционнал система не получит явные инструкции, основанные на системной функции fcntl. Помимо наследования открытых файлов, маркеры внутрифайловых позиций остаются там, где они были в момент порождения сыновнего процесса, чтобы сыновний процесс также получил доступ к маркеру позиции. При изменении позиции в родительском процессе маркер сыновнего также смещается. В этом случае мы могли бы реализовать потоковое представление данных, не создавал интерфейсный класс. Просто присоединив файловые дескрипторы канала к объектам классов ofstream и ifstream, мы сможем использовать операторы вставки (<<) и извлечения (»). Аналогично любой класс, в котором определены операторы ">>" и "<<", может выполнять операции вставки данных в канал и извлечения их оттуда без какого-либо дополнительного программирования. В программе 11.1 родительский процесс поме щ ает значение M_PI в канал (строка 30), а сыновний процесс извлекает это з н ачение из канала, используя оператор ">>" (строка24). Инструкции по выполнению и компиляции этой программы приведены в разделе «Профиль программы 11.1».