确定已终止进程的pid

10

我试图找出发送 SIGCHLD 信号的进程的 pid,我想在为 SIGCHLD 创建的信号处理程序中实现此操作。我正在尝试:

int pid = waitpid(-1, NULL, WNOHANG);

因为我想等待任何被派生出来的子进程。


你的方法是正确的,它应该可以工作。你有什么问题吗? - qrdl
1
我该如何获取发送SIGCHLD信号的进程的PID? - Hristo
2
如果您从信号处理程序中调用waitpid(),它将返回已终止子进程的pid。 - qrdl
1个回答

11
如果你像示例一样使用 waitpid(),你将会收到其中一个已经结束的子进程的PID,通常情况下,这将是唯一一个已经结束的进程,但如果出现多个已结束进程的情况,你可能会收到一个信号和许多需要回收的进程。因此,请使用:
void sigchld_handler(int signum)
{
    pid_t pid;
    int   status;
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
    {
        unregister_child(pid, status);   // Or whatever you need to do with the PID
    }
}

如果你不关心子进程的退出状态,可以用NULL替换&status

waitpid()的返回值在不同的系统中有些微差异。然而,POSIX是其中更加谨慎的一个,它表明:

如果wait()waitpid()由于子进程状态可用而返回,则这些函数应返回与报告状态的子进程的进程ID相等的值。如果wait()waitpid()由于向调用进程传递信号而返回,则应返回-1并将errno设置为[EINTR]。如果waitpid()使用options中的WNOHANG被调用,并且至少有一个由pid指定、状态不可用的子进程,以及任何由pid指定但状态不可用的进程,则返回0。否则,应返回-1,并设置errno以指示错误。


wait(3p): 如果在选项中设置了WNOHANG并调用了waitpid(),则至少有一个由pid指定的子进程状态不可用,并且任何由pid指定的进程状态都不可用,将返回0。似乎正确的条件是“> 0”,然后可能需要检查“errno”。 - LHLaurini
1
我同意,@LHLaurini,并且我已经更新了我的答案以匹配您的建议。谢谢! - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接