关于fork的一道经典面试题
这是一道面试题,问程序最终输出几个“-”:
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在产生子进程的时候,会把父进程的缓冲区也拷贝一遍。如下图所示:
如图,一条箭头表示一个进程,箭头边的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 }
则流程图如下:
结果仍然是8次,最后的fork也是有起作用的,因为只有在进程结束后才会输出缓冲区的内容。