| Назад |
В ранних версиях системы 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 могут только процессы, находящиеся "в родственных отношениях" ("родитель"-"потомок").