Кольцо из двух процессов с использованием трубы - PullRequest
0 голосов
/ 09 июня 2011

У меня есть этот пример использования pipe и dup. Предполагается создать кольцо из двух процессов, соединенных трубой. Вот код:

#include <unistd.h>

#define READ 0
#define WRITE 1

main (int argc, char *argv[]) {
 int fd[2];
 pipe(fd); //first call to pipe
 dup2(fd[READ],0);
 dup2(fd[WRITE],1);
 close(fd[READ]);
 close(fd[WRITE]);
 pipe(fd); //second call to pipe

 if (fork()==0) {
    dup2(fd[WRITE],1);
 } else
    dup2(fd[READ],0);

 close(fd[READ]);
 close(fd[WRITE]);
}

Из "кольца двух процессов" я понимаю, что выход процесса A связан с входом процесса B, а выход процесса B связан с входом процесса A.

После первого вызова pipe и двух последовательных вызовов dup2, я думаю, стандартный ввод и вывод были перенаправлены на ввод и вывод моей новой трубы.

Затем пришел второй вызов pipe, который смутил меня, поскольку я думаю, что он перезаписывает мои предыдущие значения fd. На данный момент, что происходит со стандартным вводом и выводом?

Наконец, вызов fork:

Дочерний объект перенаправляет стандартный вывод в канал?

Родитель перенаправляет стандартный ввод в канал?

Я не вижу здесь кольца.

Надеюсь, я ясно дал понять, потому что я действительно запутался.

Большое спасибо !!

1 Ответ

5 голосов
/ 09 июня 2011

Хорошо, давайте представим, что вы запустили эту вещь из терминала.Тогда у вас есть:

file 0 (stdin)  = terminal keyboard
file 1 (stdout) = terminal screen
file 2 (stderr) = terminal screen

Теперь вы запускаете pipe(fd), и у вас есть:

file 0-2 = as before
file 3 (fd[0]) = read end of pipe 1
file 4 (fd[1]) = write end of pipe 1

Теперь вы запускаете первые два dup2 s и первые два closes:

file 0 = read end of pipe 1
file 1 = write end of pipe 1
file 2 = still terminal screen
file 3-4 = now closed

Теперь вы создаете новый pipe:

file 0-2 as before
file 3 (fd[0]) = read end of pipe 2
file 4 (fd[1]) = write end of pipe 2

И теперь вы форк.В дочернем процессе вы вызываете dup2(fd[1],1) и закрываете оба fd s (ваш источник здесь не совсем прав):

file 0: read end of pipe 1
file 1: write end of pipe 2
file 2: terminal screen
file 3-4: closed

В родительском процессе вы вызываете dup2(fd[0],0) и снова закрываете обаfd s дает его:

file 0: read end of pipe 2
file 1: write end of pipe 1
file 2: terminal screen
file 3-4: closed

Итак, у нас есть родительский процесс, записывающий свой стандартный вывод в канал 1, из которого дочерний процесс читает свой стандартный вывод.Точно так же у нас есть родительский процесс, считывающий свой стандартный вывод из канала 2, в который дочерний процесс записывает свой стандартный вывод.То есть, кольцо двух процессов.

Меня всегда учили, что такого рода договоренности склонны к тупику.Я не знаю, так ли это с более современными Unix, но стоит упомянуть.

...