刚才在总结APUE第八章内容的时候,偶然联想起了以前在酷壳看到的一篇广为转载的blog--《一个fork的面试题》。其中关于这个问题的解释方式不是很符合 我的思维习惯 ,因此写了这篇文章并扩展一下《fork面试题》的问题。
现有如下C程序:
/*fork.c*/ #include <stdio.h> #include <unistd.h> int main(){ int i; for(i=0;i<2;i++){ fork(); printf("-"); } return 0; }
经过gcc fork.c编译,在当前目录下运行./a.out,请问输出多少个"-"。
原文明确的给出了答案是8个。因为在终端交互模式下,printf的默认缓冲模式是行缓冲。而原程序的printf没有换行,所以造成如下情况:
图中4157,4158,4159,4160均代表进程ID。
画一下进程树,按顺序走一遍代码,就能够理解了(假设进程执行顺序与代码顺序相同即可,此处进程执行顺序不影响输出结果)。
详细原理见APUE p110 5.4缓冲和p172 8.3 fork函数两节。
这个问题还有以下的变种:
问题1:若变成printf("-\n"),那么./a.out会输出什么?
问题2:若变成printf("-\n"),且运行./a.out > output.txt,输出会是什么?
若程序改成如下,又会输出什么。对下面的程序应用上面的问题1和问题2,输出又会是什么?
#include <stdio.h> #include <unistd.h> int main(){ printf("-"); printf("-"); fork(); fork(); return 0; }
BTW:记录一下Shell版本的fork bomb
:(){ :|:&};: