操作系统课程中fork()按height、width参数生成进程逻辑求解
fork()基础特性
fork是类Unix系统创建进程的核心系统调用,核心规则只有两点:
- 单次调用返回两次:父进程内返回值为新创建子进程的正整数PID,子进程内返回值为0
- 子进程会复制父进程当前的所有运行上下文(包括变量值、代码执行位置),父子进程从fork调用后的下一行代码开始独立执行
目标逻辑拆解
按照课程给出的进程树规则,你需要实现的逻辑可以拆分为以下几个判断分支:
- 外层循环对应
height,控制进程树的总层数,每进入一次外层循环,就生成新一层的进程 - 内层循环对应
width,控制每层父进程要创建的子进程总数 - 非最后一个子进程(内层循环
j < width-1)创建完成后直接退出所有循环,不需要再生成下一层进程 - 最后一个子进程(内层循环
j == width-1)不退出,作为下一层的父进程,进入外层循环的下一次迭代继续创建子进程 - 父进程创建完当前层所有子进程后,直接退出循环,不需要参与下一层进程的创建
现有代码修复
你当前代码注释了核心分支的跳出逻辑,导致所有进程都会反复进入循环创建多余进程,这也是你现在的输出里有多条重复PID记录的原因,修复后的完整代码如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int i, height, width; if (argc!= 3) exit(0); height = atoi(argv[1]); /* 进程树高度 */ width = atoi(argv[2]); /* 每层子进程数量 */ pid_t t; for(i=0;i<height;i++){ t = fork(); for(int j=0;j<width;j++){ if(j == width - 1){ // 内层循环走到最后一轮 if(t != 0){ // 父进程直接跳出内层循环,进入下一轮外层循环 break; } // 最后一个子进程不跳出,继续走外层循环生成下一层进程 } else { // 非最后一轮的子进程直接跳出所有循环 if(t == 0){ goto exit_loop; } } } } exit_loop: printf("I´m father %d and my child is %d\n", getppid(), getpid()); sleep(1); return 0; }
height=4、width=3的运行结果说明
按照上述逻辑运行时,总进程数为:1个初始进程 + 4层 × 3个进程 = 13个进程,最后输出的打印条数也应该是13条。你当前输出有15条,就是因为注释了跳出逻辑,导致多个进程重复进入循环创建了多余进程。
内容的提问来源于stack exchange,提问作者Jorge Pulido Lozano
相关产品推荐
相关产品推荐

