为什么 main 被调用两次?
Why is main called twice?
我刚刚了解了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。
正在缓冲。 Printf(通常)不会向标准输出写入任何内容。它只是更新一些内部数据结构。这些数据结构在 child 中重复,当流被刷新时,数据被写入。在分叉之前你应该 flush(stdout)
。
好问题!起初我有点困惑。
当您使用 printf
时,输出会被缓冲。这意味着 printf
打印的内容不会真正刷新到控制台,直到到达换行符,或者甚至直到程序终止(如果 stdout 被重定向)。
在这种情况下。父 PID 的标准输出缓冲区在 fork 期间被复制到子 PID。然后,父进程和子进程都在终止之前写入它们的缓冲区。这会导致打印重复数据。
Here 是一个 ideone link,在调用 fork()
之前包含 fflush(stdout);
。
问题来自缓冲。当 stdout
不与终端关联时,它不是行缓冲的。您写入的字符串足够短,可以保留在缓冲区中,并且仅在程序终止时才写出。因此,您首先会看到进程 27380 正在转储其缓冲区,然后是进程 27383 正在转储其缓冲区。 27380: Common code1
行在 fork 之前没有被清除,所以它在原始进程和 forked 进程的缓冲区中。在分叉之前调用 fflush()
来解决这个问题。
我刚刚了解了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。
正在缓冲。 Printf(通常)不会向标准输出写入任何内容。它只是更新一些内部数据结构。这些数据结构在 child 中重复,当流被刷新时,数据被写入。在分叉之前你应该 flush(stdout)
。
好问题!起初我有点困惑。
当您使用 printf
时,输出会被缓冲。这意味着 printf
打印的内容不会真正刷新到控制台,直到到达换行符,或者甚至直到程序终止(如果 stdout 被重定向)。
在这种情况下。父 PID 的标准输出缓冲区在 fork 期间被复制到子 PID。然后,父进程和子进程都在终止之前写入它们的缓冲区。这会导致打印重复数据。
Here 是一个 ideone link,在调用 fork()
之前包含 fflush(stdout);
。
问题来自缓冲。当 stdout
不与终端关联时,它不是行缓冲的。您写入的字符串足够短,可以保留在缓冲区中,并且仅在程序终止时才写出。因此,您首先会看到进程 27380 正在转储其缓冲区,然后是进程 27383 正在转储其缓冲区。 27380: Common code1
行在 fork 之前没有被清除,所以它在原始进程和 forked 进程的缓冲区中。在分叉之前调用 fflush()
来解决这个问题。