考虑这个例子 -
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
if (pid > 0)
{
printf("Child pid is %d\n", (int)pid);
sleep(10);
system("ps -ef | grep defunct | grep -v grep");
}
return 0;
}
在此示例中,子进程将保持僵尸状态,直到父进程终止。这个僵尸进程是如何在不被任何进程收割的情况下被清理掉的呢?
$ ./a.out
Child pid is 32029
32029 32028 0 05:40 pts/0 00:00:00 [a.out] <defunct>
$ ps -p 32029
PID TTY TIME CMD
答案1
当父进程死亡时,子进程将由 init (pid=1) 继承,它将等待它们并清理进程表。
答案2
僵尸进程的要点是在内核数据结构中留下一个占位符来保存进程的性能数据。
当父进程调用 wait(2) 时,父进程会收集性能数据,并且内核会释放数据结构。
如果父级在获取数据之前退出,则性能数据将在适当的情况下合并到父级自己的性能数据中,然后由父级的父级获取。
此外,父进程退出的子进程由进程 1(通常称为“init”)继承,然后进程 1 可以使用 wait(2) 收集任何剩余数据,从而允许内核释放数据结构。