为何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




