如果我有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的分叉进程。
简短的回答:不,“repiping”pipe1不会对之前使用pipe1的分叉进程产生影响,但最好在fork()之前声明3个管道和pipe()。
答案很长:要理解为什么,让我们首先看看当你创建一个“管道”时会发生什么,然后当你“分叉”一个进程时会发生什么。
当你调用pipe()时,它“创建一个管道(一个允许单向数据流的对象)并分配一对文件描述符。第一个描述符连接到管道的读取端;第二个描述符连接到写入端。” (这是来自man pipe页面)
这些文件描述符存储在传递给它的int数组中。
当你调用fork()时,“新进程(子进程)应该是调用进程的精确副本”(这是来自man fork()页面)
换句话说,父进程将创建一个子进程,该子进程将拥有它自己的数据副本。
因此,当子3调用管道(pipe1)时,它将创建一个新管道,并将新文件描述符存储在它自己的pipe1变量副本中,而不修改任何其他进程的pipe1。
即使你只能声明两个管道变量而只是在子3中调用pipe(),它也不是很容易阅读,而其他人(包括你自己)在以后需要查看你的代码时会被混淆。
有关fork()和pipe()的更多信息,请查看http://beej.us/guide/bgipc/output/html/multipage/index.html
我过去做过的方式,以及我再次做的方式,就是不重复使用管道,最后用N-1管道。它还取决于你是否希望同时运行两个以上的进程进行通信,如果是这样,那么你显然有重用2个管道的问题。
对于命令中的每个pipe()
字符,您需要一个管道,因此需要一次调用|
。
但是,您不需要使用三个单独的int [2]
数组来存储管道文件描述符。系统不关心存储管道文件描述符的变量 - 它们只是int
s。