子进程挂在管道内

时间:2012-05-25 00:53:51

标签: c unix process fork pipe

当我用ls | head执行此函数时,它会在打印出文件和目录后挂起第二个子进程。有人能告诉我我想念的是什么吗?提前致谢

int unipipe(char* lhs[], char* rhs[])
{
    int pfd[2];
    int status, cid;
    pid_t pid;
    char buf;
    if((lhs != NULL) && (rhs != NULL))
    {
      if(pipe(pfd) != 0)
      {
        perror("pipe");
        return -1;
      }
    if((pid = fork()) < 0)
    {
        perror("fork");
        return -1;  
    }
    else if(pid == 0)
   {
       close(1); //close the unused read end
      dup2(pfd[1], STDOUT_FILENO);
      //execute the left-hand side command
      close(pfd[0]);
      execvp(lhs[0], lhs);
       _exit(EXIT_SUCCESS);
    }

   if(setpgid(pid, 0) < 0)
   {
     perror("setpgid"); 
     return -1;
   };

  cid = waitpid(pid, &status, 0);
  if((pid = fork()) == 0)
    {
        close(0);
        dup2(pfd[0], STDIN_FILENO);
        close(pfd[1]);  //close the unused write end
        execvp(rhs[0], rhs);
        _exit(EXIT_SUCCESS);
    } 
    else
    {
           waitpid(pid, &status, 0);
    }
}

2 个答案:

答案 0 :(得分:2)

在开始第二个进程之前等待第一个进程退出。每个管道都有一个缓冲区,一旦这个缓冲区已满,I / O功能就会阻塞,等待从管道中读取几个字节,这样就可以“流入”。有可能是你的第一个进程是阻塞管道,因此永远不会退出。

我会声明两个类型为pid_t的变量,每个子节点一个,只有在两个子节点都成功启动后才等待它们。

答案 1 :(得分:0)

要使程序运行,请删除第一个:

cid = waitpid(pid, &status, 0);

在:

else
{
       waitpid(pid, &status, 0);
}

您将其替换为:

wait(); // for the fist child
wait(); // for the second child

你的程序将会运行。