You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

操作系统课程中fork()按height、width参数生成进程逻辑求解

fork()基础特性

fork是类Unix系统创建进程的核心系统调用,核心规则只有两点:

  • 单次调用返回两次:父进程内返回值为新创建子进程的正整数PID,子进程内返回值为0
  • 子进程会复制父进程当前的所有运行上下文(包括变量值、代码执行位置),父子进程从fork调用后的下一行代码开始独立执行

目标逻辑拆解

按照课程给出的进程树规则,你需要实现的逻辑可以拆分为以下几个判断分支:

  1. 外层循环对应height,控制进程树的总层数,每进入一次外层循环,就生成新一层的进程
  2. 内层循环对应width,控制每层父进程要创建的子进程总数
  3. 非最后一个子进程(内层循环j < width-1)创建完成后直接退出所有循环,不需要再生成下一层进程
  4. 最后一个子进程(内层循环j == width-1)不退出,作为下一层的父进程,进入外层循环的下一次迭代继续创建子进程
  5. 父进程创建完当前层所有子进程后,直接退出循环,不需要参与下一层进程的创建

现有代码修复

你当前代码注释了核心分支的跳出逻辑,导致所有进程都会反复进入循环创建多余进程,这也是你现在的输出里有多条重复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:03:00