我刚学会了fork,据我所知,子进程从fork调用开始执行(否则fork会递归?)。
但是在此代码中(ideone link):
int main() {
printf("%d: Common code1\n", getpid());
if (fork() != 0) {
printf("%d: Parent code\n", getpid());
} else {
printf("%d: Child code\n", getpid());
}
printf("%d: Common code\n", getpid());
}
输出结果为:
27380: Common code1
27380: Parent code
27380: Common code
27380: Common code1
27383: Child code
27383: Common code
我不明白为什么打印第4行?我可以理解它是否是从子进程打印出来的,而fork是从main打印出来的,但它是从父进程打印出来的,而fork并没有调用main。
答案 0 :(得分:8)
好问题!起初我有点困惑。
使用printf
时,输出会被缓冲。这意味着printf
打印的内容实际上不会被刷新到控制台,直到达到换行符,或者甚至直到程序终止,如果重定向stdout。
在这种情况下。在fork期间,父PID的stdout缓冲区被复制到子节点。然后,父节点和子节点在终止之前写入其缓冲区。这会导致打印重复的数据。
Here在fflush(stdout);
被调用之前包含fork()
的ideone链接。
答案 1 :(得分:3)
问题来自缓冲。当stdout
未与终端关联时,它不是行缓冲的。您编写的字符串足够短,可以保留在缓冲区内,只有在程序终止后才会写出来。因此,您首先看到进程27380转储其缓冲区,然后处理27383转储其缓冲区。行27380: Common code1
在fork之前没有被刷新,因此它位于原始进程和分叉进程的缓冲区中。在解决此问题之前立即致电fflush()
。
答案 2 :(得分:2)
缓冲。 Printf没有(通常)向stdout写任何东西。它只是更新了一些内部数据结构。这些数据结构在子进程中重复,当刷新流时,将写入数据。在你分叉前你应该flush(stdout)
。