过程
首先,创建一个 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