【问题标题】:Handling SIGCHLD will return EOF to the father, why?处理 SIGCHLD 会返回 EOF 给父亲,为什么?
【发布时间】:2010-02-24 11:55:27
【问题描述】:

我有一个小外壳,它可以创建孩子(使用 fork())并让他们使用 execvp 执行一些命令。 它还支持 & 选项,因此父亲可以同时运行其他命令。 当孩子死时,我想在控制台和孩子 pid 上写下它,所以我为 SIGCHLD 定义了一个 sighandler:

void backdeadchild(int sig)
{
 int pid, exitstat;
 pid = wait(&exitstat);
 printf("Child with pid: %d died", pid);
}

问题是在处理程序打印消息后,父亲也关闭了。 我已经设法理解 SIGCHLD 在标准输入中返回一个 EOF(并且每当父亲收到 EOF 时它就会关闭),但是为什么 SIGCHLD 返回 EOF? 如果正常的话..如何避免父亲关门?

【问题讨论】:

    标签: c fork wait eof


    【解决方案1】:

    如果孩子的stdout(或任何其他流)连接到父母的stdin,父母自然会收到EOF

    如果父母不处理它,或者父母可能会死于SIGPIPE(断管)信号。

    【讨论】:

    • 感谢您的解释,但是如何忽略那个 EOF?我试图在 SIGCHLD 信号处理程序中放置一个 getchar() ,它似乎可以工作,但是一旦我按下输入,父亲就会关闭。
    • 尝试捕捉SIGPIPE 信号 - 也许这是一个原因?
    • 它没有给出 SIGPIPE .. 我试图调试代码并且它发生了奇怪的事情.. 我在等待之后放了一个 getchar() .. 所以它读取 EOF,然后我开始调试,我给出“sleep 2 &”作为命令,孩子死了,我收到了消息,然后当我按 Enter 时它接收到 EOF 并关闭。奇怪的是,有时如果我设置断点并在按 Enter 时进行调试,它会收到 EOL 并再次打印提示,但如果我再次按 Enter,它会收到 EOF,或者有时我可以发出另一个后台命令,但按子死后入关父。
    • 可靠地调试信号几乎是不可能的。我建议在父级上使用 strace 实用程序 - 它会显示所有系统调用和捕获的信号。
    • 哇,谢谢,我想我找到了问题所在,但现在我需要一些关于如何解决它的建议。问题是我的 SIGCHLD 处理程序返回: rt_sigreturn(0) = -1 EINTR (Interrupted system call) 在我尝试使用 getchar() 删除 EOF 之后(这就是 EOF 保留在输入中的原因)。因此,一种解决方案可能是计算返回的孩子数量(在 sig 处理程序中增加全局计数器.. 但它是安全的吗?)并跳过与计数器相等的 EOF 数量.. 如果孩子没有给出 EOF i只需重置该数字。
    猜你喜欢
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 1970-01-01
    • 2016-10-31
    • 2018-10-23
    相关资源
    最近更新 更多