当父进程未能收集到系统(Kernel)通过SIGCHLD
发送的子进程的终止状态时,子进程成为僵尸进程。
系统是否再次尝试发送此进程终止状态,以便父进程尝试收集其子进程的退出状态?
会不会发生这种情况,僵尸进程会从进程表中移除?
parent 是否再次尝试读取其 child 的终止状态?
最佳答案
When a parent process fails to collect the termination status of its child process send by system(Kernel) through SIGCHLD, the child process becomes a Zombie process.
这在技术上并不准确。僵尸进程不是其父进程未能获取其终止状态的进程 - 相反,它是一个已经终止但尚未获得其终止状态的进程。
因此,当 SIGCHLD
在父进程中传递时,该进程已经是一个僵尸进程,因为它终止了,但终止状态尚未获得。
重点是,SIGCHLD
在这里有点无关紧要:父进程获取子进程的终止状态,或者没有,在这种情况下,子进程仍然是僵尸。
Does System try again to send this process termination status for the parent process to try collecting the exit status of its child?
没有。 SIGCHLD
只传递一次。如果父进程没有在信号处理程序中获得僵尸的终止状态(这不是必需的),那么它要么稍后这样做(在程序代码中的某个时刻),要么不这样做而终止(在这种情况下, zombie 的父进程成为 init 进程;init 周期性地获取孤儿的状态来清理 zombies)。
Will such thing happen and zombie process will be removed from the process table?
一旦父进程获得退出状态,僵尸进程使用的资源就会被释放。
OTOH,如果 SIGCHLD
被显式忽略(即通过将其配置更改为 SIG_IGN
),将不会有僵尸进程,因为忽略 SIGCHLD
恰恰阻止了这一点。但是,将无法获得终止状态。
来自 man 2 sigaction
:
POSIX.1-1990 disallowed setting the action for SIGCHLD to SIG_IGN.
POSIX.1-2001 allows this possibility, so that ignoring SIGCHLD can be used to prevent the creation of zombies (see wait(2)).
最后:
Does the parent try again to read this termination status of its child?
一般来说,一旦父级收集了僵尸的退出状态,再次尝试这样做会导致错误。正如我之前所说,获取僵尸的终止状态将释放僵尸正在使用的所有资源,因此您不能多次获取终止状态。
此规则的异常(exception)情况是 WNOWAIT
标志被传递给 waitid(2)
。该标志收集子进程的终止状态并使其处于可等待状态;可以在同一进程上再次使用稍后的调用来获取终止状态。
关于linux - 如果父进程收集终止状态失败一次,内核将再次尝试发送 SIGCHLD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31832224/