实现Unix进程Fork层级结构:父进程需晚于子进程终止
实现符合要求的Unix进程Fork层级结构(父进程晚于子进程终止)
根据你的需求,我整理了完整的代码实现,确保所有父进程都会等待其所有子进程终止后才输出END消息,完全符合info()函数的输出顺序要求。
完整代码实现
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> // 按需求模拟info函数的定义 #define BEGIN 0 #define END 1 void info(int type, int process_no, int thread_no) { const char* type_str = (type == BEGIN) ? "BEGIN" : "END"; printf("[%s] Process %d, Thread %d\n", type_str, process_no, thread_no); } void init() { // 可添加自定义初始化逻辑,这里留空示意 } int main() { init(); pid_t pid2, pid3, pid4, pid5, pid6, pid7, pid8, pid9; // 根进程P1启动 info(BEGIN, 1, 0); // 创建子进程P2 pid2 = fork(); if (pid2 == 0) { info(BEGIN, 2, 0); // P2创建子进程P5 pid5 = fork(); if (pid5 == 0) { info(BEGIN, 5, 0); // 模拟业务逻辑执行 sleep(1); info(END, 5, 0); exit(EXIT_SUCCESS); } else { // P2等待P5终止后再结束 waitpid(pid5, NULL, 0); info(END, 2, 0); exit(EXIT_SUCCESS); } } // 创建子进程P3 pid3 = fork(); if (pid3 == 0) { info(BEGIN, 3, 0); // P3创建子进程P6 pid6 = fork(); if (pid6 == 0) { info(BEGIN, 6, 0); sleep(1); info(END, 6, 0); exit(EXIT_SUCCESS); } // P3创建子进程P7 pid7 = fork(); if (pid7 == 0) { info(BEGIN, 7, 0); sleep(1); info(END, 7, 0); exit(EXIT_SUCCESS); } // P3等待所有子进程终止 waitpid(pid6, NULL, 0); waitpid(pid7, NULL, 0); info(END, 3, 0); exit(EXIT_SUCCESS); } // 创建子进程P4 pid4 = fork(); if (pid4 == 0) { info(BEGIN, 4, 0); // P4创建子进程P8 pid8 = fork(); if (pid8 == 0) { info(BEGIN, 8, 0); sleep(1); info(END, 8, 0); exit(EXIT_SUCCESS); } // P4创建子进程P9 pid9 = fork(); if (pid9 == 0) { info(BEGIN, 9, 0); sleep(1); info(END, 9, 0); exit(EXIT_SUCCESS); } // P4等待所有子进程终止 waitpid(pid8, NULL, 0); waitpid(pid9, NULL, 0); info(END, 4, 0); exit(EXIT_SUCCESS); } // 根进程P1等待所有子进程终止 waitpid(pid2, NULL, 0); waitpid(pid3, NULL, 0); waitpid(pid4, NULL, 0); // P1最终结束 info(END, 1, 0); return EXIT_SUCCESS; }
核心实现说明
- 严格的终止顺序保障:每个父进程通过
waitpid()显式等待所有子进程完全终止后,才输出自己的END消息,从根本上避免了父进程提前结束的问题。 - 清晰的进程层级:代码实现了P1作为根进程,衍生P2/P3/P4;P2衍生P5;P3衍生P6/P7;P4衍生P8/P9的层级结构,你可以根据实际需求调整分支数量或层级关系。
- 规范的info调用逻辑:每个进程启动时先调用
info(BEGIN),完成自身逻辑并等待子进程后再调用info(END),完全匹配需求中的消息顺序要求。 - 避免僵尸进程:通过
waitpid()回收子进程资源,既保证了终止顺序,又符合Unix进程管理的最佳实践。
典型输出顺序(调度可能微调,但父END一定在子END之后)
[BEGIN] Process 1, Thread 0 [BEGIN] Process 2, Thread 0 [BEGIN] Process 5, Thread 0 [BEGIN] Process 3, Thread 0 [BEGIN] Process 6, Thread 0 [BEGIN] Process 4, Thread 0 [BEGIN] Process 8, Thread 0 [BEGIN] Process 7, Thread 0 [BEGIN] Process 9, Thread 0 [END] Process 5, Thread 0 [END] Process 2, Thread 0 [END] Process 6, Thread 0 [END] Process 7, Thread 0 [END] Process 3, Thread 0 [END] Process 8, Thread 0 [END] Process 9, Thread 0 [END] Process 4, Thread 0 [END] Process 1, Thread 0
内容的提问来源于stack exchange,提问作者Siespi
相关产品推荐
相关产品推荐

