我刚刚学习如何在 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;
}
Run Code Online (Sandbox Code Playgroud)
按照您的预期执行:
user@fedora> ./main
starting...
parent x == 600
child x == 300
Run Code Online (Sandbox Code Playgroud)
当我从以下位置删除 \n 时,奇怪的事情发生了printf("starting...\n");:
user@fedora> ./main
starting...parent x == 600
starting...child x == 300
Run Code Online (Sandbox Code Playgroud)
为什么当我删除\n“开始...”打印两次时,它显然不应该?
请您解释一下为什么在这种情况下printf("starting...")执行两次?
谢谢你!
小智 5
您的问题不在于 fork 系统调用;而是在于 fork 系统调用。相反,它与 C 的常见 I/O 操作的缓冲方式有关。
在 C 中,printf()函数并不总是输出到终端。相反,它写入缓冲区,当缓冲区被刷新时,终端实际上被写入。当打印换行符 '\n'、缓冲区已满或使用 手动刷新缓冲区时,通常会发生这种情况fflush(stdout)。
当从初始 printf() 语句中删除 n 时,“starting...”字符串将写入代码中的缓冲区,但不会立即刷新到终端。
当 fork() 函数执行时,整个过程(包括未刷新的缓冲区)将被复制。这表明“正在启动...”现在出现在父进程和子进程的输出缓冲区中。
终止进程中任何未刷新的输出都会自动刷新。因此,对于每个过程,“starting...”都会打印两次。
将 n 保留在初始printf()指令中或在调用 fork() 之前手动刷新缓冲区是解决此问题的两种方法:
printf("starting...");
fflush(stdout);
Run Code Online (Sandbox Code Playgroud)