用C语言实现多管道



谁能给我任何想法为什么我下面的代码试图实现多个管道是不正确的?我正在实现一个父子关系,所以不允许父子-孙子关系,也就是说,所有的孩子应该并行运行。当我输入ls | cat | cat命令时,ls的内容被输出,但提示符仍然提示我输入,即使我输入另一个字符,它也不会停止。我做错了吗?

    int i;
    int pipefd[num_of_pipe][2];
    pid_t child_pid[num_of_child];
    for (i = 0; i < num_of_child; i++) {
      pipe(pipefd[i]);
      if ((child_pid[i] = fork()) == 0) {
        if (i == 0) {
          close(pipefd[i][0]);
          dup2(pipefd[i][1], STDOUT_FILENO);
          close(pipefd[i][1]);
          /* execvp something; */
        } else if (i == num_of_child - 1) {
          close(pipefd[i - 1][1]);
          dup2(pipefd[i - 1][0], STDIN_FILENO);
          close(pipefd[i - 1][0]);
          /* execvp something */
        } else {
          close(pipefd[i - 1][1]);
          dup2(pipefd[i - 1][0],0);
          close(pipefd[i - 1][0]);
          close(pipefd[i][0]);
          dup2(pipefd[i][1],1);
          close(pipefd[i][1]);
          /* execvp something */
        }
      }
    }
    int k;
    for (k = 0; k < num_of_child; k++) {
      waitpid(child_pid[k], NULL, WUNTRACED);
      printf("the %dth child returnsn", k + 1);
    }
    int j;
    for (j = 0; j < num_of_pipe; j++) {
      close(pipefd[j][0]);
      close(pipefd[j][1]);
    }
  }

问题是,您的两个cat进程都在等待其标准输入上的更多数据,因为不是所有用于它们的管道写端的文件描述符副本都被关闭。这是因为父进程构建并保存了所有管道文件描述符的数组,并且只有在派生所有子进程之后才关闭它们。因此,每个子节点都继承父节点迄今为止创建的每个打开的文件描述符,而不仅仅是为自己使用的描述符。在管道写端的所有FD关闭之前,读端不会检测到EOF。

因此,特别地,第三个子进程有一个打开的文件描述符,用于第二个子进程正在读取的管道的写端。它将在退出时关闭该进程,但它没有退出,因为第二个进程保持打开提供第三个进程的管道的写端。如果管道更长,问题会更严重。

您应该通过让主进程在不再需要文件描述符时立即关闭它们来处理这个问题,这样它们就不会被继承。在你当前的代码结构中,你可以在fork循环的底部这样做。

作为次要问题,如果实际上依赖于函数调用的返回值不会失败,则应该始终检查函数调用的返回值是否存在错误指示符。

相关内容

  • 没有找到相关文章

最新更新