Труба является однонаправленным коммуникационным каналом
между двумя
процессами и может использоваться
для поддержки коммуникаций и контроля информационного потока между двумя процессами.
Труба может принимать только определенный объем данных
(обычно 4 Кб). Если труба заполнена, процесс останавливается до тех
пор, пока хотя бы один байт из этой трубы не будет прочитан и не появится
свободное место, чтобы снова заполнить ее данными. С другой стороны,
если труба пуста, то читающий процесс останавливается до тех пор,
пока пишущий процесс не внесёт данные в эту трубу.
Труба описывается двумя дескрипторами файлов. Первый дескриптор служит для чтения, второй - для записи в трубу:
int pipe(int fd[2]);
Второй процесс для организации обмена можно создать с помощью fork(). При этом процесс-потомок наследует от родителя оба открытых дескриптора файлов. После этого, закрыв ненужные дескрипторы, необходимо указать обоим процессам, кто куда пишет и кто что читает.
В приведенном ниже примере процесс-родитель записывает данные в трубу. В этом случае закрываются дескриптор чтения (fd[0]) родительского процесса и дескриптор записи потомка. Потомок будет только читать данные из трубы:
#include <sys/wait.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#define USAGE printf("usage : %s данные\n",
argv[0]);
#define MAX 4096
int main(int argc, char *argv[]) {
int fd[2], fd1,i, n;
pid_t pid;
char buffer[MAX];
FILE *dataptr;
if(argc !=2)
{ USAGE; exit(0); }
if((fd1=open(argv[1], O_RDONLY)) < 0)
{ perror("open : "); exit(0); }
/*Устанавливаем трубу*/
if(pipe(fd) < 0)
{ perror("pipe : "); exit(0); }
/*Создаем новый процесс*/
if((pid=fork()) < 0)
{ perror("pipe : "); exit(0); }
else if(pid > 0) /*Это родитель*/ {
close(fd[0]); /*Закрываем чтение*/
n=read(fd1, buffer, MAX);
if((write(fd[1], buffer, n)) != n)
{ perror(" write : "); exit(0); }
if((waitpid(pid, NULL, 0)) < 0)
{ perror("waitpid : "); exit(0); }
}
else /*Это потомок*/ {
close(fd[1]); /*Закрываем запись*/
n=read(fd[0], buffer, MAX);
if((write(STDOUT_FILENO, buffer, n)) != n)
{ perror(" write : "); exit(0); }
}
exit(0);
}