我一直在努力理解涉及命令dup2()
,exec()
和管道的概念。
我想要实现的目标:
将程序X的输出传送到程序Y的输入。
像who | sort
有一个父级和 2 子级,其中子级负责执行程序,父级将程序传递给子级。
以下是我对管道无法理解的内容:
P1)管道被视为文件,应该是单向的,但是什么阻止我将一个管道用于多个单向通信通道?
所以,让我们说我有pipe1
和三个流程(P
- 父 - C1
,C2
,孩子们)通过分叉打开管道。所有这些进程都可以使用文件描述符。
假设我们正在正确地完成所有操作,关闭未使用的管道末端,P
现在将内容写入C1
。 使用管道在C1
和C2
之间再次进行通信有什么问题?
在写这个问题的时候,一个想法让我感到困惑:是否存在谁从中读取数据的问题,而许多进程可能同时打开它(两个进程阻塞以获取读取),即系统无法确定谁想要读取写入的缓冲数据?如果是这样,如何在系统中实现?
我真的很想了解这个概念,所以请耐心等待。
要将这个问题应用到现实生活中,这里有一些我正在处理的伪代码:
,P:
P
关闭pipe1
P
通过C1
pipe1
发送计划参数('谁')
P
关闭了写结束P
等待孩子退出C1:
C1
从pipe1
C1
dup2()
是pipe1
C1
关闭了pipe1
的两端(因为我们已经将其欺骗了)C1
execvp()
该计划(' who')C2:
C2
dup2()
读取pipe1
到stdin
的结尾,以便获取将要执行的程序的输入C2
关闭了pipe1
C2
等待来自stdin
ed C1
dup
pipe1
的输入
使用此输入C2
execvp()
的程序(&#39; sort&#39;)<小时/> 现在,如果我按照上面的描述去做,我就没有运气了。 但是,如果我引入了另一个管道
pipe2
,它看起来像这样:
的,P:
P
关闭不需要的管道pipe2
的两端P
关闭pipe1
P
通过C1
pipe1
发送计划参数(&#39;谁&#39;)
P
关闭了写结束P
等待孩子退出C1:
C1
关闭pipe2
C1
从pipe1
C1
dup2()
是pipe2
C1
关闭pipe2
C1
关闭了pipe1
的两端 - pipe2
,pipe1
在这个孩子中多余了C1
execvp()
该计划(&#39; who&#39;)C2:
C2
dup2()
读取pipe2
到stdin
C2
关闭了pipe1
C2
等待来自stdin
ed C1
dup
pipe2
的输入
C2
使用此输入执行程序sort
假设管道不应该在多个流程中重复使用,因为系统可能无法确定管理员是否需要服务&#34; ?或者还有其他原因吗?
答案 0 :(得分:2)
管道主要用于一对一通信 - 一个作家,一个读者。虽然没有什么可以阻止你拥有尽可能多的读者和作者,但这种行为常常使得它不是很有用,特别是对于多个读者:
tee
命令)。PIPE_BUF
或更小的写入是原子的。在您描述的体系结构中,您有两个独立的通信通道:P将who
发送到C1,C1将运行who
命令的输出发送到C2。在shell脚本中,这类似于
echo who | { read command; exec command; } | sort
echo who
在原始流程中执行,而不是在子shell中执行。
你的第一个提案不起作用,因为没有办法说P的输出将转到C1并且C1的输出将转到C2。它仍然是同一个管道,所以P的输出可以转到C2,C1的输出可以回到自身,或者它可能是混合物。