多路复用之select,poll

五种I/O模型

程序数据的输入,输出称之为I/O。我们在前面学习的socket套接字阶段,从网络中读取和发送数据,就属于I/O操作。当网络中没有数据可读的时候,进程就会阻塞式的等待,直到有数据准备就绪。socket套接字默认的都是阻塞的方式。


阻塞式I/O
这里写图片描述
I/O操作分为两部,第一部分是等待,第二部分是进行数据的拷贝。阻塞式I/O的特点就是当没有是数据就绪的时候,程序一直等待底层有数据准备好,然后再进行拷贝。


非阻塞式I/O
这里写图片描述
阻塞式I/O的特点就是等待效率低下,程序无法进行推进,非阻塞式I/O可以在系统调用的时候,就算底层数据没有准备好,也会进行返回,并返回错误码EWOULDBLOCK,但是非阻塞式I/O需要程序员自己进行不断的轮询调用,对CPU资源来说是一种很大的浪费。


信号驱动I/O
这里写图片描述
信号驱动I/O的特点是注册SIGIO的处理函数,在底层有数据准备好的时候,内核就给进程发送信号,在信号处理函数中调用recvfrom区拷贝底层数据。


I/O多路转接
这里写图片描述
前面的I/O操作都是等待一个文件描述符的就绪状态,而I/O多路转接是可以同时等待多个文件描述符的就绪状态,只要一个就绪,那么就返回刻度条件,并且拷贝底层数据。


异步I/O
这里写图片描述
前面的四种I/O模型都是同步方式,异步I/O是拷贝工作由内核完成,拷贝完成再通知应用程序。
再谈阻塞与非阻塞,当一个文件描述符被打开的时候,它默认是阻塞的I/O,但是我们也可以设置文件描述符的属性,设置为非阻塞式I/O。
这里写图片描述这里的cmd操作有5种功能,我们一般使用F_GETFL来获取文件描述符的标记,再使用F_SETFL设置文件描述符,设置的时候加上一个ONONBLOCK就可以把文件描述符设置为非阻塞式。


I/O多路转接之select

这里写图片描述
前面说过,select是I/O多路转接的接口,它可以同时等待多个文件述,只要有一个或者多个文件描述符的状态发生改变,就会返回,它只完成一件事情那就是等。
参数及返回值:
nfds:表示想要等待的最大文件描述符+1.
readfds,writefds,exceptfds:关心读的文件描述符集,关心写的文件描述符集,关心异常的文件描述符集。这里的fd_set类型表示文件描述符集。它可以理解为一张位图,每一个比特位的下标就表示那一个文件描述符,比特位的内容,1表示关心这个位置上的文件描述符事件。0表示不关心。同时,这三个参数都是输入输出型参数,输入表示关心那些文件描述符上上的那些事件,输出表示关心的文件描述符集上那些事件已经就绪。因此,在每一次调用select之前,都需要重新设置,我们要自己维护一个数组来保存关心的事件。fd_set类型必须用以下函数进行操作。
这里写图片描述
用来将文件描述符集的指定位清空,判断一个文件描述符是否在这个集合当中,设置一个文件描述符到文件描述符集中,把文件描述符集所有位清空。
timeval结构体:timeval用于描述一段事件,如果等待的文件描述符集在这一段时间之内没有事件发生,那么将超时,select将返回0。
select成功返回表示返回文件描述符改变的个数,返回0表示超时,返回负数代表出错。
一般情况下,我们关心文件描述符的读写情况,那么什么情况下读写条件就绪。
1.读就绪:
(1)在socket内核当中,当接受缓冲区的字节数大于等于低水位时候,这时候就可以非阻塞式的读。
(2)在TCP通信时候,对端关闭连接,此时对该socket读,返回0;
(3)监听套接字上有新的连接请求的时候。
(4)socket上有未处理的错误。
2.写就绪
(1)socket写操作被关闭,那么此时对该socket进行写,就会触发SIGPIPE信号。
(2)在socket内核中,当发送缓冲区字节数大小大于等于低水位的时候,此时可以无阻塞式的写,并且返回值大于0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值