您的位置:首页 > 职场人生

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

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

上代码:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: