简体   繁体   English

管道 output 到叉子 C

[英]Piping output to forks in C

I have a multiple processes in progs and I wish to pipe the output from one process to another sequentially.我在 progs 中有多个进程,我希望 pipe output 从一个进程顺序到另一个进程。 I believe I have already linked the stdin of a process to the read end of a previous process, and linked the stdout to the write end of the pipe. I still am not seeing an output. Am I missing something with the links here?我相信我已经将一个进程的标准输入链接到前一个进程的读取端,并将标准输出链接到 pipe 的写入端。我仍然没有看到 output。我是否遗漏了这里的链接?

  int pipeFds[numProg][2];
  
  for (int i = 0; i < numProg; i++) {
    if (pipe(pipeFds[i]) != 0) { // create pipe for each process
      printf("Failed to create pipe!");
      exit(1);
    }
    child_pid = fork();
    if (child_pid == -1) {
      printf("Error while creating fork!");
      exit(1);
    } 
    if (child_pid == 0) {
      if (i == 0) { 
        close(pipeFds[i][READ_END]); // close STDIN first process since it does not read
      } else { 
        // change stdin to read end of pipe for intermediary processes
        close(pipeFds[i]);
        dup2(pipeFds[i - 1][READ_END], STDIN_FILENO);
      }
      dup2(pipeFds[i][WRITE_END], STDOUT_FILENO); // change stdout to write end of pipe
      execvp(progs[i][0], (char *const * )progs[i]);
    } else {
      // parent process stuff
    }
  }
  
  // Close pipes except last pipe for EOF
  for (int i = 0; i < numProg - 1; i++) {
    close(pipeFds[i][READ_END]);
    close(pipeFds[i][WRITE_END]);
  }

  1. your code contains a stray close(pipeFds[i]);您的代码包含一个杂散的close(pipeFds[i]);

  2. you have to close the pipes within the // parent process stuff .你必须关闭// parent process stuff中的管道。 With your code, every child keeps the pipeFds of the previous children open.使用您的代码,每个孩子都会使之前孩子的pipeFds保持打开状态。 Eg例如

     } else { // parent process stuff if (i > 0) close(pipeFds[i - 1][READ_END]); close(pipeFds[i - 1][READ_END]); }
  3. it might be more effective to have a single fds[2] pair instead of numProg ones.使用单个fds[2]对而不是numProg对可能更有效。

Remember you need to close all pipes, in each process, for it to work.请记住,您需要关闭每个进程中的所有管道才能正常工作。

Example:例子:

If numProg=2 you create 2 pipes and 2 child processes.如果numProg=2创建 2 个管道和 2 个子进程。 Adding the parent, there a 3 processes running, and in each of them you eventually need to close all pipes.添加父级,有 3 个进程在运行,在每个进程中,您最终需要关闭所有管道。

For child_pid==0 you close the [READ_END] but never the [WRITE_END] .对于child_pid==0 ,您关闭[READ_END]但永远不会关闭[WRITE_END]

For child_pid==1 you do a close(pipeFds[1]) .对于child_pid==1你做一个close(pipeFds[1]) You need to specify [READ_END] and [WRITE_END] .您需要指定[READ_END][WRITE_END]

Then each child process exits via execvp which, however, may return control if it fails.然后每个子进程通过execvp退出,但是,如果它失败,它可能会返回控制权。 From the man page:手册页:

The exec() family of functions replaces the current process image with a new process image. exec() 系列函数用新的过程映像替换当前过程映像。 .. The exec() functions only return if an error has occurred. .. exec() 函数仅在发生错误时返回。

So you may want to add a _exit(0);所以你可能想添加一个_exit(0); after execvp to ensure each child process exits properly even if execvp fails.execvp之后确保每个子进程正确退出,即使execvp失败。

The parent process closes all pipes but the last.父进程关闭除最后一个以外的所有管道。 So in the example of NumProg=2 , [READ_END] and [WRITE_END] of pipeFd[1] both are never closed.因此,在NumProg=2的示例中, pipeFd[1][READ_END][WRITE_END]都永远不会关闭。

Lastly, the parent process should wait for all child processes to close (using while(wait(NULL);= -1); ) otherwise you may end up with zombie or orphan processes.最后,父进程应该wait所有子进程关闭(使用while(wait(NULL);= -1); ),否则你可能会得到僵尸或孤儿进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM