进程控制学习笔记(续)-- 关于fork的一道面试题

来源:互联网 发布:轰炸手机号软件下载 编辑:程序博客网 时间:2024/05/16 10:15





                             


                         在上一篇博文中,我大概的总结了一下进程控制的操作,但今天听了女神学姐的讲座,又发现了一个有趣的问题。

                    上代码:

              
    int main(int argc, char *argv[])      {          int i;          for(i=0; i<2; i++)          {              fork();              printf("-");          }                      return EXIT_SUCCESS;      }  


                     


                      答案是6个“-”吗?NO,其实是8个。


                          我们来看这句printf("-"),要知道,printf是存在缓冲区的问题的,关于缓冲,我就偷用汤圆同学博客里的一段话

                 来给大家解释吧。


                         “由于Linux的标准函数库中,有一种被称作“缓冲I/O”的操作,其特征就是对应每一个打开的文件,在内存中都

                 有一片缓冲区。每次读文件时,会连续的读出若干条记录,这样在下次读文件时就可以直接从内存的缓冲区读取;

                 同样,每次写文件的时候也仅仅是写入内存的缓冲区,等满足了一定的条件(如达到了一定数量或遇到特定字符等),

                 再将缓冲区中的内容一次性写入文件。这种技术大大增加了文件读写的速度,但也给编程代来了一点儿麻烦。比如有

                 一些数据,认为已经写入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内。”


                            而上面的代码,就是因为printf语句有缓存,它把“-”放在了缓存里,以后执行fork语句的时候,连带缓存都一起

                 被复制了,所以当第一次fork时,程序被分为父、子两个进程。先说父进程,之后执行printf语句,这时候已经有一个

                 “-”被存入缓存了,然后执行i++,i=1,继续执行第二次fork,又分为父、子两个进程,这父子两个进程也都继承了缓存

                 里的那个“-”,之后父子进程分别执行printf语句,也就是说,此时父子进程各自的缓存里已经都有两个“-”了,然后i++,

                 i=2,退出for循环,遇到return,读出缓存,各输出两个“-”,一共4个“-”,退出程序;同理,第一次fork后的子进程也执行

                了一模一样的过程,所以,最后输出的“-”一共有8个。


                 为了便于大家更好的理解,我很无耻的将一位大神的做的图偷了出来,此图很清楚的画出了整个程序的执行流程

                                             


                                                         



                     


                   当我们将上面的代码稍微修改一下,改为printf(“-\n”),即:

    int main(int argc, char *argv[])      {          int i;          for(i=0; i<2; i++)          {              fork();              printf("-\n");          }                      return EXIT_SUCCESS;      }  

                            答案就会如愿以偿的变成6个“-”了。


                   这是因为当程序遇到\n,  \t, 或者fflush,缓冲区满了, 文件描述符关闭,程序结束等,就会将数据刷出缓冲区,

            所以,在printf语句后加了\n,就会立即输出,然后清空缓存,所以下一次fork后,缓存里是没有“-”的,于是结果就

            变成输出6个“-”了。

                        

                        




文中引用的汤圆同学的博客:http://blog.sina.com.cn/s/blog_678d241901018gcf.html

文中被我偷图的大神博客:http://coolshell.cn/articles/7965.html/comment-page-1#comments









                                                         


原创粉丝点击