C语言调用2次fork()无法获得3个子进程问题求助
问题核心原因
你出现子进程计数缺失的核心原因是仅判断了第二次fork()的返回值,没有对第一次fork()生成的子进程做标记,导致第一次fork出来的子进程被误判为父进程,没有触发子进程的打印逻辑。
两次fork的进程生成逻辑复盘
连续无判断调用2次fork()确实会生成4个总进程、3个子进程,四个进程的身份及分支走向如下:
我们将初始进程记为P0:
- 第一次
fork()执行后:- P0得到返回值为第一次生成的子进程P1的PID(>0)
- 新生成的P1得到返回值为0
- 两个进程都会执行第二次
fork():- P0执行第二次
fork(),返回值为第二次生成的子进程P2的PID(>0),最终pid变量值>0,走父进程打印分支 - P1执行第二次
fork(),返回值为第三次生成的子进程P3的PID(>0),最终pid变量值>0,走父进程打印分支 - 新生成的P2得到返回值为0,走子进程打印分支
- 新生成的P3得到返回值为0,走子进程打印分支
- P0执行第二次
可以看到,第一次fork生成的子进程P1,因为第二次fork返回值>0,被你的判断逻辑归类为父进程,没有输出子进程标识,所以你只看到2个打印的子进程,实际P1也是子进程。
你输出内容里的其他异常说明
你看到重复打印Child PID: 3203的问题,是因为fork()会拷贝父进程的用户空间内存,包括标准输出缓冲区的未刷新内容:如果父进程的printf内容没有换行/手动fflush,会被子进程复制一份,后续子进程打印时会一起输出重复内容。
另外你用sleep(100)代替wait()/waitpid()回收子进程,还可能出现孤儿进程、父进程提前退出导致子进程ppid变为1(init/systemd进程)的问题。
修复方案示例
如果要识别所有子进程,可以新增标记位记录自身是否为子进程,修改核心逻辑如下:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid; int is_child = 0; pid = fork(); // fork #1 if (pid == 0) { is_child = 1; } else if (pid < 0) { perror("fork1 error"); return 1; } pid = fork(); // fork #2 if (pid == 0) { is_child = 1; } else if (pid < 0) { perror("fork2 error"); return 1; } if (is_child) { printf("Child process.\n"); printf(" |-- Child PID: %d\n", getpid()); printf(" |-- Parent PID: %d\n", getppid()); } else { printf("Root parent process\n"); printf(" |-- Parent PID: %d\n", getpid()); // 等待所有子进程退出 while(wait(NULL) > 0); printf("All child processes are now finished.\n"); } return 0; }
修改后运行即可看到3个子进程的打印输出。
内容的提问来源于stack exchange,提问作者dissidia
相关产品推荐
相关产品推荐

