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