fork()的意外输出

时间:2015-05-19 20:18:45

标签: c unix process output 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

&#34; printf(&#34; do&#34;);&#34;是之前 fork()调用所以&#34; do&#34;在输出中重复几次?

3 个答案:

答案 0 :(得分:2)

如果你看到fork的定义,它表示child和parent是完全相同的副本,并且都在下一条指令处开始执行。
现在,由于在打印换行符或显式刷新输出之前C不会刷新输出,因此“do”会保留在缓冲区中并被复制到子级。
使用方法:

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

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

您将获得预期的输出

答案 1 :(得分:0)

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

这一行创建了两个进程;其中一个是父项并运行printf语句,一个是孩子而不是。

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

两个进程都运行此语句;结果是四个过程:

  1. 父 - 父母;这将运行第一个printf并打印“do ma”
  2. 亲子;这两个都运行并打印“do ma to \ n”
  3. 子父;这既不运行也打印“do”
  4. 子 - 子;这将运行第二个并打印“do to \ n”
  5. 你遇到的问题是你认为fork返回“跳过”到下一个语句;相反,当fork返回时,您现在有两个具有不同返回值的进程。通常,在程序结束或打印换行符之前不会刷新printf。

答案 2 :(得分:0)

我认为“do”是存在的,因为它们被缓存在父输出内存中,并被复制到所有子节点。

如果您在第一个“执行”中添加“\ n”:

printf(" do\n");

你不会在分叉后看到任何“做”。