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

fork()后进程从何处开始执行?为何fork前的printf会出现两次输出?

问题解答

1. fork()执行后子进程的起始执行位置

fork()完成子进程创建后,子进程不会从头执行整个程序,会直接从fork()调用返回的位置开始往后执行,父子进程会获取到不同的fork返回值,之后各自执行对应分支的代码。

2. 输出两次1的原因

你给出的示例代码如下:

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


int main(void) {
    for (int i = 1; i < 4; i++) {
        printf("%d", i);
        int id = fork();
        if (id == 0) {
            printf("Hello\n");
            exit(0);
        } else {
            exit(0);
        }
    }
    return 0;
}

出现两次1的核心原因是标准输出的行缓冲机制:

  • 你使用printf("%d", i)输出数字1时,内容末尾没有加换行符\n,而默认情况下标准输出是行缓冲模式,只有遇到换行符、缓冲区写满、或者程序主动退出/调用fflush时,才会把缓冲区的内容真正输出到终端。
  • fork执行前,printf已经把字符1写入了父进程的标准输出缓冲区,但还没触发刷新动作,此时执行fork()会复制父进程的完整地址空间,其中就包括还没刷新的标准输出缓冲区,所以子进程的输出缓冲区里也会有一个未写入终端的1。
  • 后续父子进程各自执行到exit(0)时,都会触发缓冲区刷新,各自把缓冲区里的1输出到终端,所以最终会出现两次1。
  • 子进程后续还会执行带换行符的printf("Hello\n"),换行符会直接触发缓冲区刷新,所以最终输出结果就是11Hello。

你可以简单验证这个逻辑:把printf("%d", i);改成printf("%d\n", i)加换行,或者在printf之后加一句fflush(stdout);主动刷新缓冲区,再运行程序就只会输出一次1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:24:05