Linux网络IO模型浅析(二)非阻塞IO

Linux网络IO模型浅析(二)非阻塞IO

非阻塞IO

非阻塞IO与阻塞IO的区别从字面上就可以区分出来,在于调用读写socket的接口函数后,是否发生阻塞。
我们可以通过设置socket为非阻塞模式来进行非阻塞IO的实现。通常有以下两种方法:

  1. 使用socket提供的接口:
int sock_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
  1. 使用fnctl直接修改文件属性
int tmp_file_flag = fcntl(sock_fd, F_GETFL, 0);
int now_file_flag = tmp_file_flag | O_NONBLOCK;
fcntl(sock_fd, F_SETFL, now_file_flag);

非阻塞IO读写流程

在这里插入图片描述
从上图可看出,当调用read()阻塞函数时,即使kernel并没有将响应准备好,但是并不会block等待可读事件,而是直接返回error。从用户角度看,调用函数后会立刻得到结果,如果有数据则可以读取到并直接进行处理,否则可以自行抉择是继续read轮询还是先处理其他数据。

实际应用中,我们使用recv()进行数据读取,该接口返回值有以下几种情况:

  1. recv() 返回值大于 返回值大于 0,表示接受数据完毕,返回值即是到的字节;
  2. recv() 返回 0,表示连接已经正常断开;
  3. recv() 返回 -1,且errno 等于EAGAIN ,表示recv操作尚未完成;
  4. recv() 返回 -1,且errno 不等于EAGAIN ,表示recv操作遇到了系统错误;

非阻塞IO的应用场景

在多数情况下,即使设置了socket的文件属性为非阻塞,我们仍然需要不断调用recv接口进行数据获取,实际上消耗与阻塞IO无异。我们应该使用多路复用机制,在单线程情况下高效检测事件是否就绪,如select,epoll等,可以快速检测一个连接是否活跃。

本专栏知识点是通过<零声教育>的系统学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接0voice,查看详细的服务:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫大魔宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值