验证父进程被杀死后僵尸会被 init 进程收养
过程
首先,创建一个 docker 容器,其 entrypoint 不是可回收子进程(init-like)的命令,也不要加上 --init
选项。这样即便僵尸被 init 进程收养,也不会被马上回收,方便观察。
在容器内部进行以下操作:
// parent.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
exit(1);
}
if (pid == 0) {
// 子进程
printf("Child process (PID: %d) exiting immediately.\n", getpid());
exit(0); // 快速退出,变成僵尸
} else {
// 父进程
printf("Parent process (PID: %d), child PID: %d\n", getpid(), pid);
printf("Sleeping 60 seconds without wait() to create zombie...\n");
sleep(60); // 不调用 wait(),让子进程变成僵尸
printf("Parent exiting.\n");
}
return 0;
}
编译运行,然后在另外一个窗口将父进程 kill 掉。
root@677e804cc08c:/workspace/zombie# gcc -o parent parent.c
root@677e804cc08c:/workspace/zombie# ./parent
Parent process (PID: 308506), child PID: 308507
Sleeping 60 seconds without wait() to create zombie...
Child process (PID: 308507) exiting immediately.
Terminated
检查发现子进程成了僵尸,而且父进程成了 1 号进程。
root@677e804cc08c:/workspace/zombie $ ps -o pid,ppid,stat,cmd -p 308507
PID PPID STAT CMD
308507 1 Z [parent] <defunct>
这样的进程不会被自动清理,重启或关闭容器可以释放其资源。
相关文章
其他资料
- Choosing an init process for multi-process containers 为你的容器选择合适的 init 进程。