fork() 的意外输出

Unexpected output with fork()

我在某处读到,在 Unix 中,成功执行 fork() 后,两个进程都将在 fork() 调用后的下一条语句 处开始执行。 同时,当我 运行 C

中的这段代码时
#include <stdio.h>
int main()
{
   printf(" do ");
   if(fork()!=0) printf ("ma ");
   if(fork()==0) printf ("to \n");
   else printf("\n")

    return 0;
}

一个可能的输出是

 do ma
 do ma to
 do 
 do to

"printf(" 执行");" fork() 调用之前 "do" 为什么会在输出中重复几次?

   if(fork()!=0) printf ("ma ");

这一行创建了两个进程;其中之一是 parent 和 运行s printf 语句,一个是 child 而不是

   if(fork()==0) printf ("to \n");

两个进程运行这条语句;结果是四个过程:

  1. Parent-parent;这 运行 是第一个 printf 并打印“do ma”
  2. Parent-child;这 运行s 和打印 " do ma to \n"
  3. Child-parent;这 运行 两者都不是,并打印“ do ”
  4. Child-child;这个 运行s 第二个并打印 " do to \n"

您遇到的问题是您认为将 return "skips" 分叉到下一个语句;相反,当 fork returns 时,您现在有两个具有不同 return 值的进程。通常,在程序结束或打印换行符之前,printf 不会刷新。

如果你看到 fork 的定义,它说子进程和父进程是完全相同的副本,并且都从下一条指令开始执行。
现在,由于 C 在打印换行符或您显式刷新输出之前不会刷新输出,因此 "do" 保留在缓冲区中并也被复制到子进程中。
使用:

printf(" do ");
fflush(stdout);

printf(" do \n"); //Notice the newline in the end

你会得到预期的输出

我认为 "do" 在那里是因为它们被缓冲在复制到所有子项的父输出内存中。

如果在第一个"do"后面加上“\n”:

printf(" do\n");

分叉后您将看不到任何 "do"。