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

如何让父进程等待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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:05:31