为何移除printf的\n后,fork()会重复输出starting...?
为什么移除
printf的换行符后,starting...会重复输出? 这是stdio缓冲区机制和fork进程复制规则共同作用的结果,拆解来看:
先搞懂stdio的缓冲类型
终端环境下,printf默认使用行缓冲:只有遇到换行符\n、缓冲区存满,或者手动调用fflush(stdout)时,才会把缓冲区里的内容真正输出到终端。带
\n的情况
当你写printf("starting...\n");时,换行符触发了行缓冲刷新,starting...立刻被输出到终端,此时父进程的stdout缓冲区是空的。
之后调用fork()创建子进程,子进程会复制父进程的地址空间,但此时缓冲区里没有残留内容,所以子进程后续不会再输出starting...。不带
\n的情况
如果去掉\n,printf("starting...");的内容会暂时存放在父进程的stdout缓冲区里,没有被输出到终端。
这时候调用fork(),子进程会完整复制父进程的地址空间——包括这个还没刷新的缓冲区。
后续父进程和子进程各自执行代码:
- 父进程执行到
printf("parent x == %d\n", x);时,换行符触发缓冲刷新,会把缓冲区里的starting...和当前的输出内容一起打印出来; - 子进程执行到
printf("child x == %d\n", x);时,同样因为换行符触发缓冲刷新,会把自己复制来的缓冲区里的starting...和自身输出一起打印。
于是就出现了starting...被输出两次的情况。
- 验证方法
如果在fork()之前手动调用fflush(stdout);,不管有没有\n,starting...都只会输出一次——因为缓冲区被提前清空了,子进程复制不到残留内容。
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

