在Linux进行IO的正确姿势
浏览:3759次 出处信息
很多C/C++程序虽然在做网络编程, 但大多用别人封装好的库, 对底层不甚了解, 感觉 IO 操作不是很简单吗? 我敢说, 大多数人进行 IO 的姿势都不对, 所谓的 IO, 主要是 read()/write() 两个函数.
先说错误的 IO 读操作:
int ret = read(fd, buf, len); if(ret == -1){ exit(-1); }else if(ret == 0){ close(fd); }
看起来好像很正确的样子, 返回值也判断了, 不仅判断 -1, 还判断 0, 应该姿势正确吧? 错! 完全错误! 因为你忽略了 errno 的处理. 仔细看文档, 函数返回 -1 不能完全代表 fd 错误, 还需要结合 errno.
接下来这样改:
int ret = read(fd, buf, len); if(ret == -1){ if(errno == EINTR){ // 怎么办? }else if(errno == EAGAIN){ // 怎么办? } exit(-1); }else if(ret == 0){ close(fd); }
EINTR 表示 read() 函数调用被系统中断了, 调用者和 fd 都没有问题, 有问题的是操作系统. 而 EAGAIN 是在非阻塞 IO 时会出现. 上面的代码判断了 errno, 但不知道下一步该怎么做, 还不行.
在 Linux 下进行 IO 操作的正确姿势是:
while(1){ int ret = read(fd, buf, len); if(ret == -1){ if(errno == EINTR){ continue; }else if(errno == EAGAIN){ // 根据你和调用者的约定, 返回一个数值告诉它再次重试 // 一般是结合 select/epoll 等 IO 多路复用函数 } exit(-1); }else if(ret == 0){ close(fd); } }
没错, 在 read() 外面包一个 while(0). 以后你看到有谁写的 read() 代码不是被包含在一个死循环里, 你就可以下结论说这段代码不完善.
写 IO 的 write() 函数也是类似用法. 建议有心人可以参考 sim 框架的代码, 看看别人是怎么做的, 程序员应该多造轮子, 但不要关起门来造车.
建议继续学习:
- 关于IO的同步,异步,阻塞,非阻塞 (阅读:14481)
- Linux服务器性能评估 (阅读:8186)
- 提升磁盘IO性能的几个技巧 (阅读:7604)
- I/O模型-读书笔记 (阅读:6913)
- Innodb IO优化-配置优化 (阅读:6651)
- 查看 CPU, Memory, I/O and NetFlow (阅读:6439)
- blktrace 深度了解linux系统的IO运作 (阅读:6009)
- Linux操作系统内核3.3版本I/O Stack的流图 (阅读:5777)
- Linux IO协议栈框图 (阅读:5336)
- MySQL Tuning之浅析I/O优化 (阅读:5144)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:对象到数字 ID 的映射
后一篇:Linux下互斥量加锁与解锁操作的C代码实现 >>
文章信息
- 作者:ideawu 来源: idea's blog
- 标签: IO
- 发布时间:2015-05-11 23:25:24
建议继续学习
近3天十大热文
- [53] IOS安全–浅谈关于IOS加固的几种方法
- [52] 如何拿下简短的域名
- [51] 图书馆的世界纪录
- [50] android 开发入门
- [50] Oracle MTS模式下 进程地址与会话信
- [49] Go Reflect 性能
- [46] 【社会化设计】自我(self)部分――欢迎区
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 程序员技术练级攻略
- [29] 视觉调整-设计师 vs. 逻辑