IO多路复用详解
一、定义
-
多路: 指的是多个socket网络连接;
-
复用: 指的是复用一个线程;
-
多路复用主要有三种技术:select,poll,epoll。
如果一个I/O流进来,我们就开启一个进程处理这个I/O流。那么假设现在有一百万个I/O流进来,那我们就需要开启一百万个进程一一对应处理这些I/O流(——这就是传统意义下的多进程并发处理)。
思考一下,一百万个进程,你的CPU占有率会多高,这个实现方式及其的不合理。所以人们提出了I/O多路复用这个模型,一个线程,通过记录I/O流的状态来同时管理多个I/O,可以提高服务器的吞吐能力
1)文件描述符
简称FD,是一个从0开始递增的无符号整数,用来关联Linux中的一个文件。
2)IO多路复用
利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待CPU资源。
二、5种IO模型
[1]blockingIO - 阻塞IO
[2]nonblockingIO - 非阻塞IO
[3]IOmultiplexing - IO多路复用
[4]signaldrivenIO - 信号驱动IO
[5]asynchronousIO - 异步IO
三、多路复用技术
1)select
1.实现原理
2.调用过程
fd_set创建时将要监听的fd设置为1,执行select将未就绪的fd重置为0,再拷贝到用户空间
3.问题
- 两次拷贝耗时:需要将整个fd_set从用户空间拷贝到内核空间,select结束后还要再次拷贝到用户空间
- 遍历整个fd_set耗时:select无法具体的值是哪个fd就绪,需要遍历整个fd_set
- 监听数量有限:不超过1024
2)poll
1.实现原理
2.调用过程
3.对比select
- pollfd中在内核中采用了链表,理论上无上限
- 监听fd越多,每次遍历消耗的时间越久,性能会下降
- 未解决select其他问题
3)epoll
1.实现原理
2.调用过程
3.优点
- 监听fd无上限:基于epoll实例中的红黑树保存要监听的fd,增删改查性能高
- 无需重复拷贝:每个fd只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传递任何参数,无需重复拷贝
- 无需遍历:直接将就绪的fd拷贝到用户空间指定位置
只有存在大量的空闲连接和不活跃的连接的时候,使用epoll的效率才会比select/poll高
四:事件通知机制
- ET模式避免了LT模式可能出现的惊群现象
- ET模式最好结合非阻塞IO读取FD数据,相对LT会复杂一些