【问题标题】:child process hangs inside the pipe子进程挂在管道内
【发布时间】:2012-05-25 00:53:51
【问题描述】:

当我用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);
    }
}

【问题讨论】:

  • 在您的ls | head 示例中,unipipe 函数在哪里适合?祝你好运。
  • 我有一个函数调用解析器,它将命令“ls | head”解析为两个字符指针数组:lhs 将是 {"ls", null},rhs 是 {"head", null }。感谢您的回复!

标签: c unix process fork pipe


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    为了让你的程序运行,你删除第一个:

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

    在:

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

    您将其替换为:

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

    您的程序将运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-07
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      相关资源
      最近更新 更多