如果我有4个要管道的进程:
process1 | process2 | process3 | process4
我必须制作3个单独的管道吗
int pipe1[2];
int pipe2[2];
int pipe3[2];
或者我可以以某种方式回收像这个伪代码中的管道名称:
int pipe1[2]; // we use ONLY two pipe names: pipe1
int pipe2[2]; // and pipe2
pipe(pipe1); // getting 2 file descriptors here
pipe(pipe2); // and 2 here
for process=1 to 4
if (process==3) // getting 2 new file descriptors for
pipe(pipe1); // process3|process4 (reusing pipe1)
fork() // forking here
if (child 1) then
use pipe1
if (child 2) then
use pipe1
use pipe2
if (child 3) then
use pipe2
use pipe1 //the pipe1 that we re-pipe()ed
if (child 3) then
use pipe1 //the pipe1 that we re-pipe()ed
这会有用吗?我不确定重复管道1是否会影响以前使用pipe1的分叉进程。
答案 0 :(得分:2)
简答: 不,“重新管理”pipe1不会对以前使用pipe1的分叉进程产生影响,但最好在fork()之前声明3个管道和pipe()。
答案很长: 要理解为什么,让我们首先看看当你创建一个“管道”时会发生什么,然后当你“分叉”一个过程时会发生什么。
当你调用pipe()时,它 “创建一个管道(一个允许单向的对象) 数据流)并分配一对文件描述符。第一个描述符连接到管道的读取端;第二个连接到写端。“(这是来自man pipe页面)
这些文件描述符存储在您传入其中的int数组中。
当你调用fork()时,“新进程(子进程)应该是调用进程的精确副本”(这是来自man fork()页面)
换句话说,父进程将创建一个子进程,该子进程将拥有它的自己的数据副本。
因此当子3调用pipe(pipe1)时,它将创建一个新管道,并将新文件描述符存储在pipe1变量的自己的副本中,而不修改任何其他进程的pipe1。
即使你只能声明两个管道变量而只是在子3中调用pipe(),它也不是很容易阅读,而其他人(包括你自己)在以后需要查看你的时候会被混淆代码。
有关fork()和pipe()的更多信息,请查看http://beej.us/guide/bgipc/output/html/multipage/index.html
答案 1 :(得分:1)
我过去做过的方式,以及我再做一次的方式,就是不重复使用管道,最后用N-1管道。这还取决于你是否希望同时运行两个以上的进程进行通信,如果是这样,那么你显然在重用2个管道时遇到了问题。
答案 2 :(得分:1)
对于命令中的每个pipe()
字符,您需要一个管道,因此需要一次调用|
。
但是,您不需要使用三个单独的int [2]
数组来存储管道文件描述符。系统不关心存储管道文件描述符的变量 - 它们只是int
s。