0

我正在尝试在 C 中实现多管道,以运行多个命令,如 shell。我已经创建了一个链接列表(在我的代码中称为 t_launch),如果您键入“ls | grep src | wc”,它看起来像这样:

wc -- 管道 -- grep src -- 管道 -- ls

每个 PIPE 节点都包含一个来自 pipe() 函数的 int tab[2](当然,每个 PIPE 节点都有一个 pipe() 调用)

现在我正在尝试执行这些命令:

int     execute_launch_list(t_shell *shell, t_launch *launchs)
{
   pid_t pid;
   int   status;
   int   firstpid;

   firstpid = 0;
   while (launchs != NULL)
   {
      if ((pid = fork()) == -1)
         return (my_error("Unable to fork\n"));
      if (pid == 0)
      {
         if (launchs->prev != NULL)
         {
            close(1);
            dup2(launchs->prev->pipefd[1], 1);
            close(launchs->prev->pipefd[0]);
         }
         if (launchs->next != NULL)
         {
            close(0);
            dup2(launchs->next->pipefd[0], 0);
            close(launchs->next->pipefd[1]);
         }
        execve(launchs->cmdpath, launchs->words, shell->environ);
      }
      else if (firstpid == 0)
        firstpid = pid;
      launchs = launchs->next == NULL ? launchs->next : launchs->next->next;
   }
   waitpid(firstpid, &status, 0);
   return (SUCCESS);
}

但这不起作用:看起来命令不会停止阅读。例如,如果我输入“ls | grep src”,“src”将从 grep 命令中打印出来,但 grep 会继续读取并且永远不会停止。如果我输入“ls | grep 源代码 | wc”,没有打印出来。我的代码有什么问题?谢谢。

4

1 回答 1

1

如果我正确理解您的代码,您首先pipe会为每个 PIPE 调用 shell 进程。然后,您继续进行fork每个过程。

虽然您确实关闭了进程中每个子管道的未使用端,但child此过程存在两个问题:

  1. 每个孩子都有每一根管子,不属于它的管子不关

  2. 父(shell)进程打开了所有管道。

因此,所有管道都打开了,孩子们不会得到 EOF。

顺便说一句,你需要wait()为所有的孩子,而不仅仅是最后一个。考虑第一个孩子在关闭后进行一些长时间计算的情况stdout,但请记住,关闭后的任何计算或副作用stdout,即使是短暂的,都可以在接收器进程终止后进行排序,因为多处理本质上是非确定性的。

于 2013-07-11T17:21:04.083 回答