如何让父进程等待fork创建的全部10个子进程退出?
解决父进程等待所有子进程退出的问题
你的问题核心在于原代码中父进程创建每个子进程后就暂停,且若在循环内直接调用wait,会导致父进程阻塞,无法同时创建所有子进程。正确的做法是先批量创建所有子进程,再统一等待它们全部退出。
方法1:循环调用wait()等待所有子进程
wait()会阻塞父进程直到任意一个子进程退出,我们只需循环调用10次(对应10个子进程),就能确保所有子进程都被回收:
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> int main() { pid_t pid; int cnt; // 第一步:批量创建10个子进程 for(cnt = 1; cnt <= 10; cnt++) { switch (pid = fork()) { case -1: perror("fork error"); break; case 0: printf("%d: 子进程,PID=%d,PPID=%d\n", cnt, getpid(), getppid()); sleep(10); exit(0); default: printf("%d: 父进程,PID=%d,PPID=%d,创建子进程PID=%d\n", cnt, getpid(), getppid(), pid); // 此处不暂停也不等待,继续创建下一个子进程 break; } } // 第二步:等待所有子进程退出 printf("父进程开始等待所有子进程退出...\n"); int status; pid_t exited_pid; for(cnt = 1; cnt <= 10; cnt++) { exited_pid = wait(&status); if(exited_pid == -1) { perror("wait error"); break; } if(WIFEXITED(status)) { printf("子进程PID=%d 正常退出,退出码=%d\n", exited_pid, WEXITSTATUS(status)); } } printf("所有子进程已退出,父进程结束\n"); return 0; }
方法2:使用waitpid()循环等待直到无剩余子进程
如果不确定子进程数量,或需要更灵活的等待逻辑,可循环调用waitpid(-1, &status, 0),直到它返回-1且errno为ECHILD(表示已无子进程需要等待):
#include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> #include <errno.h> int main() { pid_t pid; int cnt; // 创建10个子进程 for(cnt = 1; cnt <= 10; cnt++) { switch (pid = fork()) { case -1: perror("fork error"); break; case 0: printf("%d: 子进程,PID=%d,PPID=%d\n", cnt, getpid(), getppid()); sleep(10); exit(0); default: printf("%d: 父进程,PID=%d,PPID=%d,创建子进程PID=%d\n", cnt, getpid(), getppid(), pid); break; } } // 等待所有子进程退出 printf("父进程开始等待所有子进程退出...\n"); int status; pid_t exited_pid; while(1) { exited_pid = waitpid(-1, &status, 0); if(exited_pid == -1) { if(errno == ECHILD) { // 无剩余子进程,退出循环 break; } else { perror("waitpid error"); exit(1); } } if(WIFEXITED(status)) { printf("子进程PID=%d 正常退出,退出码=%d\n", exited_pid, WEXITSTATUS(status)); } } printf("所有子进程已退出,父进程结束\n"); return 0; }
关键说明
- 原代码
default分支的sleep(10)会导致父进程串行创建子进程,而非并发创建,因此需要移除。 - 必须先完成所有子进程的创建,再进入等待循环,这样10个子进程会同时运行,父进程最后统一回收它们。
- 通过
WIFEXITED和WEXITSTATUS宏,可以判断子进程是否正常退出,并获取其退出码,便于调试和状态跟踪。
内容的提问来源于stack exchange,提问作者Newb
相关产品推荐
相关产品推荐

