logo search
Конспект Граур

Пример. Реализация конвейера.

. Конвейер – это две программы (два процесса), которые исполняются параллельно и при этом стандартный вывод первой программы посылается на стандартный ввод второй программы, т.е. по мере того, как 1-й процесс генерирует свой вывод, он сразу же выдается на ввод второму процессу. Реализуется это очень легко с помощью каналов. Первым делом порождается канал, затем происходит порождение процесса потомка. В процессе потомке с помощью системного вызова dup2(), записывающая сторона канала дублируется на стандартный вывод, после чего системный вызов dup2() открывает второй дескриптор и теперь дескриптор с номером 1, описывающий стандартный вывод, будет смотреть в канал (весь вывод будет помешен в канал) после чего закрываются ненужные дескрипторы, записывающий в канал и читающий, и вызывается замена тела процесса на ту программу, которая собственно является первой программой. В процессе отце происходит всё наоборот, здесь в читающей стороне канала открывается второй дескриптор с номером 0 (стандартный ввод), это означает, что в дальнейшем весь стандартный ввод будет браться из канала, происходит тоже самое, закрываются ненужные дескрипторы, записывающий в канал и читающий, и происходит замена тела программы на программу wc.

Пример реализации конвейера print|wcвывод программы print будет подаваться на вход программы wc. Программа print печатает некоторый текст. Программа wc считает количество прочитанных строк, слов и символов.

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

int main(int argc, char **argv)

{

int fd[2];

pipe(fd); /*организован канал*/

if (fork())

{

/*процесс-родитель*/

dup2(fd[1], 1); /* отождествили стандартный вывод с файловым дескриптором канала, предназначенным для записи */

close(fd[1]); /* закрыли файловый дескриптор канала, предназначенный для записи */

close(fd[0]); /* закрыли файловый дескриптор канала, предназначенный для чтения */

exelp(“print”, ”print”, 0); /* запустили программу print */

}

/*процесс-потомок*/

dup2(fd[0], 0); /* отождествили стандартный ввод с файловым дескриптором канала, предназначенным для чтения*/

close(fd[0]); /* закрыли файловый дескриптор канала, предназначенный для чтения */

close(fd[1]); /* закрыли файловый дескриптор канала, предназначенный для записи */

execl(“/usr/bin/wc”, ”wc”, 0); /* запустили программу wc */

}