C 中 fork 调用的意外输出
Unexpected output on a fork call in C
我在学校作业中遇到了这个,但它没有产生我认为应该产生的结果:
int main() {
printf("c");
fork();
printf("d");
}
我知道这段代码有几处不好的地方(即 main 中没有参数,fork 中的 return 值没有变量,末尾没有 return 语句,等),但这就是它的呈现方式,无论如何它与我的问题无关。
此代码产生输出:
cdcd
据我了解,当调用 fork 时,parent 和 child 都会在 fork 调用后 resume/begin 在线。基于此,我预计输出为:
cdd
当然假设fork调用成功。任何人都可以向我解释为什么第二次打印“c”,即使它在 fork 调用之前就已经在线上了吗?
谢谢!
M_MN
您看到 c
两次的原因是 fork()
复制了未打印的缓冲输出。您可以在 fork()
:
之前刷新输出流
fflush(stdout);
或者您可以将 stdout
设置为无缓冲,但您应该在第一次调用 printf()
之前先执行此操作:
setvbuf(stdout, NULL, _IONBF, 0);
这是我猜测的情况。 printf
写入流 stdout
。由于您在打印 "c"
后没有刷新 stdout
也没有在新行中结束该字符串,因此该字符位于 user-space 缓冲区中。当您调用 fork
时,子进程获得父进程的虚拟地址 space 的副本,包括缓冲文本。当两个程序都退出时,它们的缓冲区被刷新,因此 "c"
出现了两次。
尝试在调用 fork
之前添加 fflush(stdout);
。
您在刷新标准输出之前分叉了您的程序(即:数据仍在输出缓冲区中)。只需调用 fflush(stdout)
来修复它:
❯ cat test.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("c");
fflush(stdout);
fork();
printf("d");
}
[22:14:01]~/devel
❯ clang test.c -o test
[22:14:07]~/devel
❯ ./test
cdd[22:14:09]~/devel
我在学校作业中遇到了这个,但它没有产生我认为应该产生的结果:
int main() {
printf("c");
fork();
printf("d");
}
我知道这段代码有几处不好的地方(即 main 中没有参数,fork 中的 return 值没有变量,末尾没有 return 语句,等),但这就是它的呈现方式,无论如何它与我的问题无关。
此代码产生输出:
cdcd
据我了解,当调用 fork 时,parent 和 child 都会在 fork 调用后 resume/begin 在线。基于此,我预计输出为:
cdd
当然假设fork调用成功。任何人都可以向我解释为什么第二次打印“c”,即使它在 fork 调用之前就已经在线上了吗?
谢谢! M_MN
您看到 c
两次的原因是 fork()
复制了未打印的缓冲输出。您可以在 fork()
:
fflush(stdout);
或者您可以将 stdout
设置为无缓冲,但您应该在第一次调用 printf()
之前先执行此操作:
setvbuf(stdout, NULL, _IONBF, 0);
这是我猜测的情况。 printf
写入流 stdout
。由于您在打印 "c"
后没有刷新 stdout
也没有在新行中结束该字符串,因此该字符位于 user-space 缓冲区中。当您调用 fork
时,子进程获得父进程的虚拟地址 space 的副本,包括缓冲文本。当两个程序都退出时,它们的缓冲区被刷新,因此 "c"
出现了两次。
尝试在调用 fork
之前添加 fflush(stdout);
。
您在刷新标准输出之前分叉了您的程序(即:数据仍在输出缓冲区中)。只需调用 fflush(stdout)
来修复它:
❯ cat test.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("c");
fflush(stdout);
fork();
printf("d");
}
[22:14:01]~/devel
❯ clang test.c -o test
[22:14:07]~/devel
❯ ./test
cdd[22:14:09]~/devel