【问题标题】:how a process know's which child ended?一个进程如何知道哪个孩子结束了?
【发布时间】:2013-11-17 18:12:32
【问题描述】:

当一个子进程终止时,他会向父进程发送SIGCHLD。现在,如果父进程有多个子进程,父进程如何知道哪个子进程发送了信号?

【问题讨论】:

    标签: c signals sigchld


    【解决方案1】:

    wait() 系统调用返回终止子的pid。您可以在您的 SIGCHLD 处理程序中调用 wait() 以确定哪个孩子终止了。

    来自man page

           wait(): on success, returns the process ID of the terminated child;
       on error, -1 is returned.
    

    【讨论】:

    • 如果我使用wait,它将一直保持到所有子进程结束,但我希望它继续运行而不管其他子进程。
    • @orenma wait() 将在至少一个孩子终止时返回,这在您的进程收到SIGCHLD 信号时发生。手册页:“wait() 系统调用暂停调用进程的执行,直到其子进程之一终止”。但是,如果没有可用的孩子,您可以使用waitpid(-1, &status, WNOHANG); 立即返回。注意WNOHANG 标志。
    • +1 实际上,在 CHLD 信号处理程序本身内部的循环中调用 waitpid()wait()waitpid() 都是 async-signal-safe)是一项长期存在的技术。
    • @shanet 谢谢,这真的很有帮助。但是当信号不是在进程终止时而是在它被暂停或类似的情况下发送时会发生什么?
    • 不要引用我,因为我自己没有尝试过,但是当进程暂停时,它会发送SIGSTOPSIGTSTP。只有在子进程终止时才会通知父进程。我想知道这是否不是 100% 正确,因为我知道当子进程暂停时 bash 会显示给我。也许@pilcrow 可以跳到这里,因为他/她似乎比我更好地处理信号,或者你必须自己做一些研究/打开另一个问题。
    【解决方案2】:

    除了@shanet's answer 中的wait() 系列调用之外,SIGCHLD 本身还携带该信息。

    传递给三参数信号处理程序 (SA_SIGINFO) 的 siginfo_t 成员的 si_pid 成员包含孩子的 PID。

    【讨论】:

    • 难道不能为多个事件调用一次处理程序吗?如果是这样,这种方法就不可靠了。
    • @ikegami,更准确地说,SIGCHLD 不需要排队,因此在等待时生成的 CHLD 会丢失。但是,确实 触发处理程序 的 SIGCHLD 会携带生成它的子进程的 PID。
    猜你喜欢
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2017-01-21
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多