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

C语言多次调用fork()后进程输出错误且无法终止问题

问题原因分析

1. 进程创建逻辑导致进程数远超预期

你这段代码总共会产生10个独立进程,计算逻辑如下:

  • 初始进程执行int n1 = fork()后生成2个进程:
    • 父进程(n1>0):后续执行int n5 = fork(),再新增1个子进程,该分支总共2个进程
    • 第一个子进程(n1==0):连续执行3次fork,每次fork都会让当前进程数翻倍,最终产生2^3=8个进程
      所有10个进程都会执行最后的printf语句。

2. 打印顺序混乱、输出不连续的原因

  • 系统调度器对进程的执行顺序是随机的,父子进程没有固定的先后执行顺序,不会按照代码编写顺序依次打印
  • 如果父进程先于子进程执行完毕退出,当前shell会立刻弹出提示符,后续还没执行的子进程再打印内容时,就会出现在提示符之后,看起来像是程序重新运行才输出的内容。

3. 父进程PID错误的原因

当父进程先退出后,还没运行完的子进程会变成孤儿进程,被系统的init进程(PID通常为1,部分系统为systemd等管理进程)收养,所以此时调用getppid()返回的是收养进程的PID,而不是原来的父进程PID,这就是你看到的"PID错误"现象。

4. 程序无法正常终止的原因

你在父进程中没有调用wait()/waitpid()等待子进程执行完毕,父进程跑完自己的逻辑就直接退出了,shell感知到主进程退出就会认为程序执行完成,但后台还有孤儿进程在运行,给你一种程序没终止的错觉。如果有子进程进入异常阻塞状态,还会一直残留在后台占用资源。

修复方案

如果要实现所有进程按预期打印、父进程等所有子进程退出后再结束,可以参考修改后的代码:

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

int main(int argc, char** argv) {
    int n1 = fork();

    if (n1 == 0) {
        int n2 = fork();
        int n3 = fork();
        int n4 = fork();
        printf("%d with parent %d\n", getpid(), getppid());
        fflush(stdout);
        exit(0);
    } else if (n1 > 0) {
        int n5 = fork();
        if (n5 == 0) {
            printf("%d with parent %d\n", getpid(), getppid());
            fflush(stdout);
            exit(0);
        }
    }

    while (wait(NULL) > 0);
    printf("%d with parent %d\n", getpid(), getppid());
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:48:01