You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何fork出的子进程getppid()获取的父PID与父进程自身PID不一致?

为什么子进程的getppid()和父进程的getpid()不一致?

嘿,这个问题的核心原因其实很简单——你的父进程比子进程先执行完并退出了

看你的输出就能发现端倪:父进程的输出先打印出来,紧接着就显示Process returned 0,说明父进程已经彻底结束了。而子进程是在父进程退出之后才轮到调度执行,这时候它已经变成了「孤儿进程」,操作系统会自动把它交给系统里的收养进程来接管(在现代Linux环境中,这个进程通常是systemd,PID可能是1或者像你这里的1017,不同系统环境会有差异),所以子进程调用getppid()拿到的是这个收养进程的ID,而不是原来父进程的29207。

怎么验证这个结论?

你可以给父进程加个延迟,让它等子进程先完成打印再退出,修改后的代码如下:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h> // 别忘了加这个头文件,printf依赖它
int main(){
    pid_t pid;
    pid=fork();
    switch(pid) {
        case 0: // 子进程分支
            printf("case 0:\nchild %d\nparent %d\n", getpid(), getppid());
            break;
        default: // 父进程分支
            sleep(2); // 让父进程休眠2秒,给子进程先执行的机会
            printf("default:\npid(child) %d\nparent %d\n", pid, getpid());
            break;
    }
    return 0;
}

运行这段代码,你会看到子进程打印的父PID和父进程的PID完全一致了,因为父进程这时候还活着,没有退出。

额外补充两点

  • fork()创建出父子进程后,它们的执行顺序是由操作系统调度器决定的,完全不确定,你的例子刚好碰到父进程先被调度执行完毕的情况。
  • 操作系统收养孤儿进程是为了避免它们变成僵尸进程,后续的资源回收工作会由这个系统收养进程负责。

内容的提问来源于stack exchange,提问作者Vincenzo Cosi

火山引擎 最新活动