关于fork的一道经典面试题

时间:2021-12-20 03:30:16

这是一道面试题,问程序最终输出几个“-”:

 1 #include<stdio.h>
 2 #include<sys/types.h>
 3 #include<unistd.h>
 4 int main()
 5 { 
 6     int i;
 7     for(i = 0; i < 2; i++)
 8     {
 9         fork();
10         printf("-");
11     }
12     wait(NULL);
13     
14     return 0;
15 } 

正确答案是8个,关键在于prinf("-")只是将字符放到了进程的缓冲区而不输出,而fork在产生子进程的时候,会把父进程的缓冲区也拷贝一遍。如下图所示:

关于fork的一道经典面试题

如图,一条箭头表示一个进程,箭头边的0 "-"表示此时该进程的输出缓冲区中没有“-”,1 “-”表示有1个。经过fork后,缓冲区被拷贝,而经过一次prinf,则缓冲区中的“-”增加一个,最终当进程结束的时候,将缓冲区的内容输出。

如果将printf("-")换成printf("-\n"),或者在printf("-")后加一句fflush(stdout),则每次printf的时候就将“-”输出,缓冲区里面不再有东西,这样执行多少次prinf就输出多少次“-”,结果是6次。

 

如果将fork()与prinf("-")交换位置,变成

 1 #include<stdio.h>
 2 #include<sys/types.h>
 3 #include<unistd.h>
 4 int main()
 5  { 
 6     int i;
 7     for(i = 0; i < 2; i++)
 8      {
 9          printf("-");
10          fork();
11      }
12      wait(NULL);
13      
14     return 0;
15  } 

则流程图如下:

关于fork的一道经典面试题

结果仍然是8次,最后的fork也是有起作用的,因为只有在进程结束后才会输出缓冲区的内容。