fork 与 IO 流的缓冲模式
浏览:3206次 出处信息
刚才帮人解决了一个问题,记录一下。
一个 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大量数据的内存占用分析 (阅读:4618)
- github 上 Fork 别人的项目后的常用的操作指南 (阅读:4413)
- 多线程下的fork及写时复制导致的性能问题 (阅读:3510)
- 极不和谐的 fork 多线程程序 (阅读:3280)
- PHP输出缓冲及其应用 (阅读:2441)
- 设置 linux 命令缓冲模式 (阅读:1512)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:RedHat Enterprise Linux 生命周期
文章信息
- 作者:Chen3feng's space 来源: Chen3feng's space
- 标签: fork 缓冲
- 发布时间:2009-11-02 12:25:40
建议继续学习
近3天十大热文
-
[930] WordPress插件开发 -- 在插件使用 -
[130] 解决 nginx 反向代理网页首尾出现神秘字 -
[51] 如何保证一个程序在单台服务器上只有唯一实例( -
[51] 海量小文件存储 -
[50] 整理了一份招PHP高级工程师的面试题 -
[49] CloudSMS:免费匿名的云短信 -
[48] 全站换域名时利用nginx和javascri -
[48] 用 Jquery 模拟 select -
[47] Innodb分表太多或者表分区太多,会导致内 -
[46] ps 命令常见用法
