我是否必须为C中的每对进程创建一个新管道?

时间:2011-10-23 23:23:01

标签: c process pipe pseudocode

如果我有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的分叉进程。

3 个答案:

答案 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。