我只是在学习如何在 C 中使用 fork(),但我很难理解执行流程。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
printf("starting...\n");
int x = 100;
int rc = fork();
if (rc < 0) {
printf("unable to fork\n");
exit(-1);
} else if (rc == 0) {
x = x + 200;
printf("child x == %d\n", x);
} else {
x = x + 500;
printf("parent x == %d\n", x);
}
return 0;
}
如您所想的那样执行:
user@fedora> ./main
starting...
parent x == 600
child x == 300
当我移除时发生了奇怪的事情 来自
printf("starting...\n");
:
user@fedora> ./main
starting...parent x == 600
starting...child x == 300
为什么当我删除
\n
“开始...”打印两次,而它显然不应该?
请你解释一下为什么在这种情况下
printf("starting...")
被执行了两次?
谢谢!
您的问题不在于 fork 系统调用;相反,它与 C 的公共 I/O 操作的缓冲方式有关。
在 C 中,
printf()
函数并不总是输出到终端。相反,它写入一个缓冲区,当缓冲区被刷新时,终端实际上被写入了。这通常发生在换行符 '
' 被打印出来,缓冲区已满,或者缓冲区被手动刷新 fflush(stdout)
.
当从初始 printf() 语句中删除 n 时,“starting...”字符串将写入代码中的缓冲区,但不会立即刷新到终端。
整个过程,包括未刷新的缓冲区,然后在创建 fork() 函数时被复制。 这表明“starting...”现在出现在父进程和子进程的输出缓冲区中。
终止进程的任何未刷新输出都会自动刷新。为此,对于每个过程,“starting...”被打印两次。
在初始
printf()
指令中保留 n 或在调用 fork() 之前手动刷新缓冲区是解决此问题的两种方法:
printf("starting...");
fflush(stdout);