io在Linux,在Linux进行IO的正确姿势

原标题:在Linux进行IO的正确姿势

很多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 框架的代码, 看看别人是怎么做的, 程序员应该多造轮子, 但不要关起门来造车.返回搜狐,查看更多

责任编辑:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值