为何循环调用fork()的程序打印时终端提示符先于部分hello输出
关于fork循环代码执行时终端提示符提前输出的原因解释
代码基础行为说明
你运行的C代码如下:
#include <stdio.h> #include <unistd.h> int main() { int i; int n = 4; for(i=0; i<n; i++) fork(); printf("hello\n"); return 0; }
- 每次执行
fork()都会将当前进程一分为二,4次循环后总共有2^4=16个独立进程,每个进程都会执行一次printf,因此总共有16行hello输出,和你观测到的输出数量一致。
提示符提前出现的核心原因
- shell 仅会等待你直接启动的*前台主进程(也就是原始的父进程)*执行结束,不会主动等待该父进程衍生出的所有子进程。
- 原始父进程完成4次fork循环、打印完自身的
hello后就会直接退出,shell检测到前台运行的任务已经结束,就会立刻输出新的终端提示符,等待用户下一次输入。 - 此时还没有执行完的子进程会变为孤儿进程,被系统的init进程(或systemd)接管继续运行,它们后续执行printf输出的内容,就会直接打印在已经出现的终端提示符之后,也就出现了你看到的提示符夹在
hello中间的现象。
修复验证方法
如果希望所有hello都打印完成后再出现终端提示符,可以在父进程中添加逻辑等待所有子进程退出后再结束,代码修改示例如下:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> // 新增等待子进程所需的头文件 int main() { int i; int n = 4; for(i=0; i<n; i++) fork(); printf("hello\n"); // 循环等待所有子进程退出,没有子进程时wait返回-1,结束循环 while(wait(NULL) > 0); return 0; }
修改后运行程序,所有16行hello都会在终端提示符出现前打印完成。
内容的提问来源于stack exchange,提问作者Raz0rmaddnes
相关产品推荐
相关产品推荐

