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

fork/exec程序输出不符:B打印两次、C三次的原因解析

进程fork与execvp执行结果差异分析

程序代码

int main(int argc,char *argv[]){
    int i;
    for(i=1;i<3;i++){
        if (fork()==0){
            printf("A");
            execvp("./prog2",&argv[1]);
            printf("B");
            exit(1);
        } 
        printf("C");
    }
    printf("D");
    return 0;
}

问题描述

执行命令 ./prog1 后,预期结果为:A打印2次,B打印0次,C打印2次,D打印1次。但实际运行结果为:A打印2次,B打印2次,C打印3次,D打印1次。需要解释差异原因。

差异原因解析

1. B打印2次的原因:execvp执行失败

execvp("./prog2", &argv[1]) 执行失败的核心原因是当前工作目录下不存在可执行文件prog2。当execvp调用失败时,子进程不会被新程序替换,会继续执行后续代码:打印B,然后调用exit(1)退出。因为循环执行了2次,每次fork出的子进程都会走到这一步,所以B被打印2次。

2. C打印3次的原因:printf缓冲区的继承

printf默认采用行缓冲模式,当输出内容不包含换行符时,数据会暂存在进程的用户态缓冲区中,直到缓冲区满、进程退出或显式调用fflush才会刷新到终端。

具体执行流程:

  • 第一次循环:
    父进程调用fork()创建子进程1,子进程进入if分支执行printf("A")(内容存入缓冲区);父进程则执行printf("C")(内容存入自身缓冲区)。子进程1因execvp失败,打印B后退出,退出时刷新缓冲区输出AB;父进程缓冲区此时存有1个C。
  • 第二次循环:
    父进程再次调用fork()创建子进程2,此时父进程缓冲区中的C会被复制到子进程2的缓冲区中。父进程继续执行printf("C"),自身缓冲区变为CC;子进程2进入if分支执行printf("A")(缓冲区变为CA),因execvp失败打印B(缓冲区变为CAB),退出时刷新缓冲区输出CAB。
  • 循环结束后:
    父进程执行printf("D"),缓冲区变为CCD,进程退出时刷新缓冲区输出CCD。

统计下来:父进程输出2个C,子进程2输出1个继承来的C,总共3次C。

3. A和D的次数符合预期

  • A:每个子进程进入if分支后都会打印1次,共2次。
  • D:只有初始父进程会在循环结束后打印1次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:25:59