【问题标题】:Killing forked child kills parent?杀死分叉的孩子杀死父母?
【发布时间】:2012-01-03 21:10:20
【问题描述】:

我陷入了这种奇怪的行为,我有我的主程序和一个分叉的孩子。它们像这样通过管道传输(数字是文件描述符):

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

所以 parent 从 stdin 获取输入,但将 stdoutstderr 重定向到两个管道。孩子已经关闭了它的 stdin 并使用管道的读取端来代替。

然后我有一个函数可以杀死孩子:

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

孩子被成功杀死,但问题是父母本身也被杀死。我检查了孩子的PID,它是正确的。

那么为什么父母会死呢?

【问题讨论】:

  • 我喜欢这个问题的名字。还有艺术。
  • 父母收到了什么信号?
  • 杀死孩子后,父母是否尝试写入标准输出或标准错误?如果是这样,它会因为 SIGPIPE 而死。您是否正在更改 SIGCHLD 的处理方式?

标签: c linux process ipc


【解决方案1】:

在子进程退出后,父进程向其 fd 1 或 fd 2 写入的任何尝试都将导致内核向父进程发送 SIGPIPE。 SIGPIPE 的默认行为是进程终止。这可能就是正在发生的事情。

【讨论】:

  • 这确实是问题所在。只需 close()ing 父级中的管道即可解决它。现在我只需要找到一种方法来重置标准输出和标准错误。
  • @Pithikos dup() stdout/stderr 在创建管道之前。关闭管道后, dup2() 再次将它们返回到文件描述符 1/2。
【解决方案2】:

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

【讨论】:

  • 也许等待被终止的孩子是个好主意,你知道,僵尸......
猜你喜欢
  • 2016-11-09
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 2019-01-18
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多