fork()调用打印更多的时间比预期的
的代码看起来是这样的fork()调用打印更多的时间比预期的
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
printf("Starting process id is %d\t", getpid());
if (fork() == 0)
fork();
else {
fork();
fork();
exit(0);
}
printf("%d\t", getpid());
}
对于输出像预期的那样在那里追踪的大部分。也就是说,如果我们开始与ID n
我们得到被打印n+1
和n+5
。但是,当我打印启动进程ID它打印5次,我不知道为什么。任何帮助,将不胜感激
输出看起来像这样
开始的进程ID是27252 PC @ PC-VirtualBox的:〜/桌面$ 开始porcess ID是27252起porcess ID是27252启动 porcess ID是27252 27253起porcess ID是27252起 进程ID是27252 27257
不过我本来期望看到
凝望进程ID是27252 27253 27257
你的初始printf
不换行结束,并且通过连接到终端默认stdout
被行缓冲。因此,当你fork
,在stdout
缓冲区不是空的,并且当每个子进程上exit
刷新,它刷新留在它继承了缓冲区中的数据相同。
要解决,做到以下几点:
所以,如果我理解正确,当我打电话的printf()什么我尝试打印,而我的程序正在运行保存在一个缓冲区,然后当程序终止缓冲区被打印到标准输出? – Mitchel0022
@ Mitchel0022:通常的规则是'stderr'没有缓冲,'stdout'在连接到终端时被行缓冲(所以当它看到输出中的换行符或底层缓冲区填充时,先冲洗缓冲区),和“stdout”连接到其他任何东西,并且所有其他打开的句柄都被块缓冲(所以它们在缓冲区填充时进行刷新,缓冲区的大小被定义为实现)。当手柄关闭时(也就是在程序退出时隐式发生),缓冲区也被刷新,这就是为什么你所有的孩子都在打印。 – ShadowRanger
啊,用'\ n'替换'\ t'确实强制它清除缓冲区。谢谢你的解释 – Mitchel0022
这是因为printf
是缓冲你的输出,没有立即刷新到该设备。
所以,当你叉,过程也的副本具有缓冲的信息和各过程将输出完整的字符串。
在每次分岔之前,您应该尝试拨打fflush(stdout)
(并且可能还有fsync(fileno(stdout))
,具体取决于您的平台)。
大谢谢! – Mitchel0022
你什么输出,以及你期望什么样的产出? – aschepler
叉/行缓冲多重复数据删除:( –