2011-11-22 77 views
12

我进入这个奇怪的行为,我有我的主程序和分叉的孩子。他们管道像这样(的数字文件描述符):杀死分叉的孩子杀死父母吗?

___parent___ 
|   |      ____child_____ 
| 0 stdin |     |    | 
| 1 pipe1[1]----------.   | 1 stdout | 
| 2 pipe2[1]----------.\   | 2 stderr | 
|____________|   \`----------> 3 pipe1[0] | 
         `----------> 5 pipe2[0] | 
            |______________| 

所以家长获取输入从标准输入重定向标准输出标准错误两个管道。该孩子已关闭其标准杆,并使用管道的读取端。

然后,我有一个函数只杀死孩子:

void killChild(){ 
    printf("Killing %d\n", (int)childID); 
    fflush(stdout); 
    kill(childID, SIGKILL); 
    waitpid(childID, NULL, 0); // getting rid of the zombie 
} 

孩子被成功地杀死了,但问题是,父母本身就会被杀死为好。我检查了孩子的PID,这是正确的。

那么,为什么父母死了?

+5

我喜欢这个问题的名称。和艺术。 – Gabe

+3

父母收到了什么信号? – hochl

+5

在杀死孩子后父母是否尝试写入stdout或stderr?如果是这样,它因SIGPIPE而死亡。你在改变SIGCHLD的处理吗? –

回答

13

任何企图通过父写入其FD 1或2的fd后孩子退出将导致内核发送SIGPIPE父。 SIGPIPE的默认行为是进程终止。这可能是发生了什么事。

+1

确实是这个问题。只需在父节点上关闭管道即可解决问题。现在我只需要找到重置stdout和stderr的方法。 – Pithikos

+3

@Pithikos dup()stdout/stderr创建管道之前。关闭管道后,dup2()再次返回到文件描述符1/2。 – nos

2

你需要处理SIGPIPESIGCHLD信号 - 可能只是忽略它们 - 你应该没问题。

+2

也许这是一个好主意,等待终止的孩子,你知道,僵尸... – hochl

+1

他已经这样做了,所以我没有对此发表评论。 – pajton