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

execvp调用失败时各字符打印次数疑问:为何C打印3次?

execvp调用失败时的字符打印次数分析

当execvp()调用失败时,运行以下代码实际得到C打印3次,但逻辑推导预期是2次,想明确正确结果及原因:

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;
}

我的预期是:父进程会将C存入缓冲区,第一次循环后存1个C,第二次循环后存2个C,最终打印CCD;两个子进程各自打印AB后退出,因此预期A打印2次、B打印2次、C打印2次、D打印1次。但实际运行结果为A打印2次、B打印2次、C打印3次、D打印1次。


实际运行结果是正确的,核心原因是**fork()会复制父进程的输出缓冲区**,结合标准输出的行缓冲特性,具体分析如下:

  1. 标准输出的行缓冲特性:默认情况下,标准输出采用行缓冲模式,只有遇到换行符、缓冲区满或程序退出时才会刷新缓冲区。printf("C")未添加换行符,输出内容会暂存在缓冲区中,不会立即打印。

  2. 具体执行流程:

    • 第一次循环(i=1):
      • 父进程调用fork()创建子进程1。
      • 子进程1进入if分支:执行printf("A")("A"进入子进程1的缓冲区),execvp失败后执行printf("B")("B"进入缓冲区),随后exit(1)。exit会自动刷新缓冲区,子进程1输出AB。
      • 父进程在fork()后执行printf("C"),"C"进入父进程的缓冲区,此时缓冲区内容为[C]。
    • 第二次循环(i=2):
      • 父进程调用fork()创建子进程2,此时父进程缓冲区已有一个"C",子进程2会完整复制该缓冲区,初始缓冲区内容为[C]。
      • 子进程2进入if分支:执行printf("A")(缓冲区变为[C,A]),execvp失败后执行printf("B")(缓冲区变为[C,A,B]),随后exit(1)。exit刷新缓冲区,子进程2输出CAB。
      • 父进程在fork()后执行printf("C"),缓冲区内容变为[C,C]。
    • 循环结束后:
      • 父进程执行printf("D"),缓冲区变为[C,C,D],return 0触发程序退出时刷新缓冲区,输出CCD。
  3. 字符打印次数统计:

    • A:子进程1、子进程2各1次 → 共2次
    • B:子进程1、子进程2各1次 → 共2次
    • C:子进程2输出1次,父进程输出2次 → 共3次
    • D:父进程输出1次 → 共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:27:03