进程控制学习笔记(续)-- 关于fork的一道面试题
2013-07-29 15:25
302 查看
在上一篇博文中,我大概的总结了一下进程控制的操作,但今天听了女神学姐的讲座,又发现了一个有趣的问题。
上代码:
答案是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个。
为了便于大家更好的理解,我很无耻的将一位大神的做的图偷了出来,此图很清楚的画出了整个程序的执行流程。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/08/ef8a1aa654426a27daeba8498c42ee82.jpg)
当我们将上面的代码稍微修改一下,改为printf(“-\n”),即:
答案就会如愿以偿的变成6个“-”了。
这是因为当程序遇到\n, \t, 或者fflush,缓冲区满了, 文件描述符关闭,程序结束等,就会将数据刷出缓冲区,
所以,在printf语句后加了\n,就会立即输出,然后清空缓存,所以下一次fork后,缓存里是没有“-”的,于是结果就
变成输出6个“-”了。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/08/373cdbebf1835b49a5dd533e51892fd8.jpg)
文中引用的汤圆同学的博客:http://blog.sina.com.cn/s/blog_678d241901018gcf.html
文中被我偷图的大神博客:http://coolshell.cn/articles/7965.html/comment-page-1#comments
上代码:
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个。
为了便于大家更好的理解,我很无耻的将一位大神的做的图偷了出来,此图很清楚的画出了整个程序的执行流程。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/08/ef8a1aa654426a27daeba8498c42ee82.jpg)
当我们将上面的代码稍微修改一下,改为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个“-”了。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201912/08/373cdbebf1835b49a5dd533e51892fd8.jpg)
文中引用的汤圆同学的博客:http://blog.sina.com.cn/s/blog_678d241901018gcf.html
文中被我偷图的大神博客:http://coolshell.cn/articles/7965.html/comment-page-1#comments
相关文章推荐
- 进程控制——fork系统调用学习笔记
- Android(java)学习笔记188:关于构造代码块,构造函数的一道面试题(华为面试题)
- [Linux学习笔记]进程概念及控制
- RHCE7学习笔记28――控制服务和进程
- 关于fork()的一道经典面试题
- 学习笔记 -- 进程控制 API
- 关于一道java面试题的学习感触
- Linux进程线程学习笔记:进程控制
- linux学习笔记:关于linux守护进程与终端的通信
- 操作系统学习笔记——进程控制
- 关于linux系统调用fork()的一道面试题
- 学习笔记13——.关于inode和block的两道企业面试题
- UNIX环境编程学习笔记(18)——进程管理之进程控制三部曲
- UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习
- 学习笔记:linuxc第七章—进程控制 下篇
- 【ARM&Linux】学习笔记之Linux下多进程控制
- APUE 学习笔记(六) 进程控制
- PCNTL--PHP进程控制扩展学习笔记
- 操作系统学习笔记(4)——进程的控制与调度
- linux学习笔记:关于多级fork后的scanf输入的疑惑