Linux下re-parenting机制示例代码运行原理相关问题咨询
代码运行流程与re-parenting机制说明
你给出的示例代码如下:
#include <stdio.h> #include <unistd.h> int main() { if (fork() == 0) { // child process printf("My parent's PID is %d\n", getppid()); sleep(2); printf("My parent's PID is %d\n", getppid()); } else { // parent process sleep(1); } // both processes printf("Terminated\n"); }
对应运行输出:
My parent's PID is 18892 Terminated shell $ My parent's PID is 1 Terminated
核心问题先解答
- 父进程确实被执行了
Terminated会打印两次,父进程和子进程各执行一次末尾的公共printf语句,所以你会看到两次输出
完整运行时序拆解
- 程序启动后,初始父进程执行
fork()系统调用,成功创建子进程:fork()给父进程返回子进程的PID(非0值),给子进程返回0,两个进程后续走不同的分支逻辑
- 子进程进入
if分支:- 先执行第一条
printf,打印当前父进程PID(也就是初始父进程的PID,对应你输出里的18892) - 调用
sleep(2),进入2秒的暂停状态
- 先执行第一条
- 父进程进入
else分支:- 调用
sleep(1),进入1秒的暂停状态 - 1秒后
sleep结束,没有其他分支逻辑要执行,直接走到两个进程共有的末尾代码,执行printf("Terminated\n")打印Terminated,随后父进程直接退出
- 调用
- 父进程退出时,还在
sleep状态的子进程成为孤儿进程,触发Linux的re-parenting机制:系统自动将孤儿进程交给init进程(PID为1)收养 - 再过1秒,子进程的
sleep(2)结束:- 执行第二条
printf,此时父进程已经退出,getppid()返回收养它的init进程的PID 1 - 同样走到末尾的公共代码,执行
printf("Terminated\n")打印第二次Terminated,随后子进程退出
- 执行第二条
输出里shell $出现在中间的原因
父进程是shell启动的前台任务,父进程退出后shell认为前台任务已经执行完成,就提前打印了命令提示符shell $,这时候还没退出的子进程后续的输出会直接打印在提示符之后,就出现了你看到的shell $ My parent's PID is 1的效果。
内容的提问来源于stack exchange,提问作者Redman
相关产品推荐
相关产品推荐

