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

如何使用fork()实现图示进程树?本人仅掌握fork()基础,求技术指导

嘿,别担心,用fork()构建你需要的进程树其实没那么难!我会结合你给出的树结构(根进程A → 子进程B → 孙进程C,同时根进程A还会生成子进程D),一步步带你实现——毕竟刚接触fork()的话,理清进程分支逻辑是核心关键~

用fork()实现目标进程树的分步指南

先明确核心逻辑

fork()是Unix/Linux系统创建进程的核心调用,它的特点是调用一次,返回两次:

  • 在父进程中,返回新创建的子进程PID(正数)
  • 在子进程中,返回0
  • 如果创建失败(比如系统资源不足),返回-1

我们要做的,就是通过判断fork()的返回值,让不同进程执行对应的分支代码,从而构建出想要的树结构。


完整代码实现

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t pid;

    // 第一步:根进程A创建子进程B
    pid = fork();
    if (pid == -1) {
        perror("创建进程B失败");
        return 1;
    } else if (pid == 0) {
        // 这里是子进程B的执行逻辑
        printf("我是进程B,PID:%d,父进程(A)PID:%d\n", getpid(), getppid());

        // B创建自己的子进程C
        pid_t c_pid = fork();
        if (c_pid == -1) {
            perror("创建进程C失败");
            return 1;
        } else if (c_pid == 0) {
            // 这里是子进程C的执行逻辑
            printf("我是进程C,PID:%d,父进程(B)PID:%d\n", getpid(), getppid());
            // C没有子进程,直接退出
            return 0;
        } else {
            // B等待C执行完毕再退出,避免出现僵尸进程
            wait(NULL);
            printf("进程B已等待进程C结束,即将退出\n");
            return 0;
        }
    } else {
        // 这里回到根进程A的执行逻辑
        printf("我是进程A,PID:%d,父进程PID:%d\n", getpid(), getppid());

        // A创建另一个子进程D
        pid_t d_pid = fork();
        if (d_pid == -1) {
            perror("创建进程D失败");
            return 1;
        } else if (d_pid == 0) {
            // 这里是子进程D的执行逻辑
            printf("我是进程D,PID:%d,父进程(A)PID:%d\n", getpid(), getppid());
            // D没有子进程,直接退出
            return 0;
        } else {
            // A等待所有子进程(B和D)执行完毕再退出
            wait(NULL); // 等待第一个子进程结束
            wait(NULL); // 等待第二个子进程结束
            printf("进程A已等待所有子进程结束,即将退出\n");
            return 0;
        }
    }
}

关键代码细节解释

  1. 进程分支的区分:每一次fork()后,我们通过返回值判断当前是父进程还是子进程,从而进入对应的逻辑块,避免所有进程重复执行相同的创建代码。
  2. wait()的作用:父进程调用wait(NULL)会阻塞自己,直到子进程执行完毕,这样可以避免子进程成为「僵尸进程」(已经退出但父进程没回收其资源的进程)。
  3. 错误处理:每次fork()后都检查返回值是否为-1,用perror()打印错误信息——这是新手也该养成的良好编程习惯,方便排查问题。

运行效果参考

编译运行后,你会看到类似这样的输出(PID是系统随机分配的):

我是进程A,PID:1234,父进程PID:987
我是进程B,PID:1235,父进程(A)PID:1234
我是进程D,PID:1236,父进程(A)PID:1234
我是进程C,PID:1237,父进程(B)PID:1235
进程B已等待进程C结束,即将退出
进程A已等待所有子进程结束,即将退出

你也可以在程序运行时,用pstree命令实时查看进程树结构,验证是否符合你的预期~

内容的提问来源于stack exchange,提问作者sun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:10:01