【问题标题】:Last child forked will not die最后一个孩子分叉不会死
【发布时间】:2011-12-13 15:48:20
【问题描述】:

我有两次主进程分叉,从而创建了两个孩子。两个孩子像这样互相吹奏:

ls | more

现在的问题是第二个孩子永远不会死。这是为什么?管道里最后一个孩子什么时候真的死了?

删除一个 wait() 调用会显示 ls | more 的预期结果,但会带来一些更奇怪的行为(终端卡住等)。

这是我的代码:

int main(){
  printf("[%d] main\n", getpid());
  int pip[2], i;
  pipe(pip);

  /* CHILDREN*/
  for (i=0; i<2; i++){
    if (fork()==0){

      /* First child */
      if (i==0){
        printf("[%d] child1\n", getpid());
        close(1); dup(pip[1]);
        close(pip[0]);
        execlp("ls", "ls", NULL);}

      /* Second child */
      if (i==1){
        printf("[%d] child2\n", getpid());
        close(0); dup(pip[0]);
        close(pip[1]);
        execlp("more", "more", NULL);}
    }  
  }
  wait(NULL);  // wait for first child
  wait(NULL);  // wait for second child
  return 0;
}

【问题讨论】:

  • 这个问题的标题听起来很暴力。
  • @Marlon 哈哈直到现在才看到它!

标签: c linux pipe kill children


【解决方案1】:

在写入端被所有用户关闭之前,管道的读取端不会获得 EOF 标记。两个孩子的父母仍然打开了管道的两端,所以more 没有看到 EOF(从 read() 返回 0),并继续等待更多输入。

【讨论】:

    【解决方案2】:

    ps axw 核对,确实是more 不会死。然后阅读wait 的手册页。查看wait的返回状态。

    (提示:看看是什么导致了“僵尸”过程。我认为等待不会像你想象的那样。)

    【讨论】:

    • 用“ps aux | grep more”也做到了。我可以看到第二个孩子还活着,提示只是挂起(等待孩子)。
    猜你喜欢
    • 2013-08-08
    • 2012-01-03
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多