如何使用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; } } }
关键代码细节解释
- 进程分支的区分:每一次
fork()后,我们通过返回值判断当前是父进程还是子进程,从而进入对应的逻辑块,避免所有进程重复执行相同的创建代码。 wait()的作用:父进程调用wait(NULL)会阻塞自己,直到子进程执行完毕,这样可以避免子进程成为「僵尸进程」(已经退出但父进程没回收其资源的进程)。- 错误处理:每次
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
相关产品推荐
相关产品推荐

