我有管道和重复使用的这个例子.它应该创建一个由管道连接的两个进程的环.这是代码:
#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]);
}
Run Code Online (Sandbox Code Playgroud)
从"两个过程的循环"我理解过程A的输出连接到过程B的输入,过程B的输出连接到过程A的输入.
在第一次调用pipe之后,以及dup2的两次成功调用之后,我认为标准输入和输出被重定向到我的新管道的输入和输出.
然后,第二次调用管道让我感到困惑,因为我认为它会覆盖我以前的fd值.在这一点上标准输入和输出发生了什么?
最后,fork调用:
孩子是否将标准输出重定向到管道?
父级是否将标准输入重定向到管道?
我在这里看不到戒指.
我希望自己清楚明白,因为我真的很困惑.
非常感谢你!!
好的,我们假装你已经从终端开始做这件事了.然后你有:
file 0 (stdin) = terminal keyboard
file 1 (stdout) = terminal screen
file 2 (stderr) = terminal screen
Run Code Online (Sandbox Code Playgroud)
现在你跑了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
Run Code Online (Sandbox Code Playgroud)
现在你运行前两个dup2s和前两个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
Run Code Online (Sandbox Code Playgroud)
现在你做一个新的pipe:
file 0-2 as before
file 3 (fd[0]) = read end of pipe 2
file 4 (fd[1]) = write end of pipe 2
Run Code Online (Sandbox Code Playgroud)
现在你分叉了.在子进程中,您调用dup2(fd[1],1)并关闭两个fds(您的源代码不在此处):
file 0: read end of pipe 1
file 1: write end of pipe 2
file 2: terminal screen
file 3-4: closed
Run Code Online (Sandbox Code Playgroud)
在您调用的父进程中dup2(fd[0],0),再次关闭两个fds给它:
file 0: read end of pipe 2
file 1: write end of pipe 1
file 2: terminal screen
file 3-4: closed
Run Code Online (Sandbox Code Playgroud)
所以我们让父进程将其stdout写入管道1,子管道从中读取stdin.类似地,我们让父进程从管道2读取它的stdin,孩子正在将它的stdout写入.即,一个两个过程的环.
我总是被告知这种安排很容易陷入僵局.我不知道更现代的Unix是否属实,但值得一提.