Назад

Содержание

Вперед

1.7.2. Каналы межпроцессного обмена.

    В ранних версиях системы UNIX основным средством для обмена данными между задачами были каналы межпроцессного обмена (pipes).

    Для создания канала используется системный вызов pipe( ). Его формат следующий:

#include <inistd.h>

int pipe (int fd[2]);

    Аргументом функции является указатель на массив двух целых чисел, в котором функция возвращает два файловых дескриптора. Первый из них предназначен для чтения данных из канала, второй - для записи в него.

    После создания pipe, процесс может при помощи обычного системного вызова write( ) выводить данные в него, а затем вводить их, вызывая соответственно функцию read( ). При выполнении вызова fork( ) дескрипторы канала наследуются процессом-"потомком". Таким образом, оба процесса получают возможность обмениваться данными.

    Ограничением в данном случае является то, что канал должен работать лишь в одну сторону. Либо "родитель" должен писать, а "потомок" читать, либо наоборот. В первом случае для передачи данных от процесса-"родителя" к процессу-"потомку", первый должен закрыть fd[0], а второй fd[1]. Во втором случае выполняются противоположные действия. Если предполагается передавать данные в обе стороны, необходимо создать два канала.

    Приведенный ниже пример иллюстрирует использование pipe. Процесс-"родитель" создает канал и порождает новый процесс. Затем выводит в pipe строку, которую "потомок" читает и выводит на терминал.

#include <stdio.h>
#include <inistd.h>

int main ()
{
  int n, fd [2];
  pid_t pid;
  char line [128];
    if (pipe (fd) == -1)
    perror ("pipe: ошибка создания канала"); 
      if ( (pid = fork ( )) == -1)
    perror ("fork: ошибка создания процесса"); 
      if (pid > 0) {    /*процесс-"родитель" */
    close (fd [0] );
    write (fd [1], "Hello, world!\n", 12);
  }
  else {	        /*процесс-"потомок" */
    memset (line, 0, 120);
    close (fd [1] );
    n = read (fd [0], line, 120);
    puts (line);
  }
      exit (0);
}

    К недостаткам каналов следует отнести то, что они имеют свойство переполняться. Это значит, что если вывод в pipe происходит более интенсивно, чем ввод из него, возникает ошибка, и ядро системы генерирует сигнал SIGPIPE. Существенным ограничением является и то, что взаимодействовать через pipe могут только процессы, находящиеся "в родственных отношениях" ("родитель"-"потомок").