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

问题描述 投票:1回答:3

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

c process pipe pseudocode
3个回答
2
投票

简短的回答:不,“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


1
投票

我过去做过的方式,以及我再次做的方式,就是不重复使用管道,最后用N-1管道。它还取决于你是否希望同时运行两个以上的进程进行通信,如果是这样,那么你显然有重用2个管道的问题。


1
投票

对于命令中的每个pipe()字符,您需要一个管道,因此需要一次调用|

但是,您不需要使用三个单独的int [2]数组来存储管道文件描述符。系统不关心存储管道文件描述符的变量 - 它们只是ints。

© www.soinside.com 2019 - 2024. All rights reserved.