验证父进程被杀死后僵尸会被 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>

这样的进程不会被自动清理,重启或关闭容器可以释放其资源。

相关文章

其他资料