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

为何移除printf的\n后,fork()会重复输出starting...?

为什么移除printf的换行符后,starting...会重复输出?

这是stdio缓冲区机制和fork进程复制规则共同作用的结果,拆解来看:

  1. 先搞懂stdio的缓冲类型
    终端环境下,printf默认使用行缓冲:只有遇到换行符\n、缓冲区存满,或者手动调用fflush(stdout)时,才会把缓冲区里的内容真正输出到终端。

  2. 带\n的情况
    当你写printf("starting...\n");时,换行符触发了行缓冲刷新,starting...立刻被输出到终端,此时父进程的stdout缓冲区是空的。
    之后调用fork()创建子进程,子进程会复制父进程的地址空间,但此时缓冲区里没有残留内容,所以子进程后续不会再输出starting...。

  3. 不带\n的情况
    如果去掉\n,printf("starting...");的内容会暂时存放在父进程的stdout缓冲区里,没有被输出到终端。
    这时候调用fork(),子进程会完整复制父进程的地址空间——包括这个还没刷新的缓冲区。
    后续父进程和子进程各自执行代码:

  • 父进程执行到printf("parent x == %d\n", x);时,换行符触发缓冲刷新,会把缓冲区里的starting...和当前的输出内容一起打印出来;
  • 子进程执行到printf("child x == %d\n", x);时,同样因为换行符触发缓冲刷新,会把自己复制来的缓冲区里的starting...和自身输出一起打印。
    于是就出现了starting...被输出两次的情况。
  1. 验证方法
    如果在fork()之前手动调用fflush(stdout);,不管有没有\n,starting...都只会输出一次——因为缓冲区被提前清空了,子进程复制不到残留内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:45:04