打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
linux 进行IO读写的正确方法

2015.05

很多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);    }    // proc    break;}

没错, 在 read() 外面包一个 while(1). 以后你看到有谁写的 read() 代码不是被包含在一个死循环里, 你就可以下结论说这段代码不完善.

写 IO 的 write() 函数也是类似用法. 建议有心人可以参考 sim 框架的代码, 看看别人是怎么做的, 程序员应该多造轮子, 但不要关起门来造车.

Related posts:

  1. Linux 核心编程 – fsync, write
  2. 软件体系结构模式-层
  3. Lighttpd mod_fastcgi源码分析
  4. 构建C1000K的服务器(1) – 基础
  5. 经典的 TCP socket 读取报文错误
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
如何判断socket已经断开
send返回值
Linux文件操作的主要接口API及相关细节
UC头条:Linux基础IO[文件操作]
linux非阻塞的socket EAGAIN的错误处理
网络编程
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服