孤儿进程是指在操作系统中,父进程结束了或者父进程已经退出,但是子进程仍然在继续运行的情况下,这个子进程就被称为孤儿进程(爹没了)。当父进程退出时,操作系统会将孤儿进程的父进程设置为init进程(在Unix/Linux系统中通常是进程号为1的init进程),init进程会接管孤儿进程,负责对其进行处理,以确保孤儿进程能够正常终止并释放资源(init接管)。

孤儿进程的特点包括:

  1. 孤儿进程的父进程已经退出或者结束。
  2. 孤儿进程的父进程ID会被设置为1,即init进程。
  3. 孤儿进程会被init进程接管,init进程会负责回收孤儿进程的资源,防止其成为僵尸进程。

通过将孤儿进程的父进程设置为init进程,操作系统确保了即使父进程退出,孤儿进程仍然能够正常终止,避免资源泄漏和系统性能问题。 代码模拟一下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
 
// orphan.c
int main() {
    pid_t pid;
    pid = fork();
    printf("Parent ppid: %d\n", getppid());
    if (pid == -1) {
        printf("fork error.\n");
        exit(1);
    } else if (pid == 0) // child
    {
        printf("I'm child, pid = %d, parent pid = %d\n", getpid(), getppid());
        sleep(1);
        printf("==> Child pid = %d, parent pid = %d\n", getpid(), getppid());
        printf("child process exit.\n");
    } else {
        printf("I'm parent process.\n");
        printf("parent process exit.\n");
    }
    return 0;
}
 

输出:

gcc orphan.c && ./a.out
Parent ppid: 27312
I'm parent process.
parent process exit.
Parent ppid: 43312
I'm child, pid = 43313, parent pid = 43312
Child pid = 43313, parent pid = 1423
child process exit.

这里1423号进程是由于桌面环境中systemd配置和常见的服务器配置不一样导致的:

ps -aux | grep 1423
jcheng      1423  0.0  0.0  21452 11520 ?        Ss   12:55   0:00 /usr/lib/systemd/systemd --user