fork 与 IO 流的缓冲模式
浏览:2625次 出处信息
刚才帮人解决了一个问题,记录一下。
一个 CGI 程序,输出一些内容,然后就 fork 子进程做一些耗时的操作,父进程马上退出以便返回结果给浏览器。
现象是 CGI 的内容在浏览器上看到的是两次重复的,在程序的开头加日志记录运行次数,发现每次刷新浏览器,进程也只运行一次。如果不 fork,结果就是正确的。如果 fork,即使父子进程都马上返回,故障依然存在。但是在命令行调用这个程序,输出是正常的。
猜测跟某些全局对象的析构有关,把 fork 后 return 0 改为 _Exit(0),浏览器就报错了,没收到完整的数据,其实是什么都没收到。
恍然大悟,应该是 cout 的缓冲造成的,fork 前加了一句 cout.flush(),问题解决了。
分析了一下原因:
stdio流和C++ IO流都有三种工作模式:无缓冲,行缓冲,全缓冲。
运行库会根据标准输出是否是终端而做出不同的优化:
当程序在命令行前台启动时,设置为行缓冲模式,以便输出结果能尽快地被人看到。
cgi 方式被调用时,运行库检测到标准输出被重定向,就开启全缓冲以提高性能,glibc 下缓冲区的大小是 4K,缓冲区不填满,就不会实际输出。这种情况下fork 的时候因为缓冲区还不满,实际并未输出,fork 后,父子进程分别结束,cout 析构的时候要输出所有的未输出的内容,因此现象上看起来就是输出了两次。
把原来的程序输出重定性到文件即可复现这个 bug。
建议继续学习:
- PHP查询MySQL大量数据的内存占用分析 (阅读:3919)
- github 上 Fork 别人的项目后的常用的操作指南 (阅读:3846)
- 极不和谐的 fork 多线程程序 (阅读:2754)
- 多线程下的fork及写时复制导致的性能问题 (阅读:2700)
- PHP输出缓冲及其应用 (阅读:1700)
- 设置 linux 命令缓冲模式 (阅读:954)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:RedHat Enterprise Linux 生命周期
文章信息
- 作者:Chen3feng's space 来源: Chen3feng's space
- 标签: fork 缓冲
- 发布时间:2009-11-02 12:25:40
建议继续学习
近3天十大热文
- [70] Twitter/微博客的学习摘要
- [67] IOS安全–浅谈关于IOS加固的几种方法
- [64] 如何拿下简短的域名
- [64] android 开发入门
- [63] find命令的一点注意事项
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [59] Oracle MTS模式下 进程地址与会话信
- [58] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则