#2021年底大盘点#IO多路复用 select/poll/epoll

select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

1、select

select 函数监视的文件多路复用技术是指利用一个信道同时传输多路信号描述符分3类,分别是writefds、readfds、和exceptfd多路复用技术分为三种s。调用后select函linux系统安装数会阻塞,直到有描述副就绪(有数据 可读、可写、或者有exc多路复用器ept),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过文件描述符遍历fdset,来找到就绪的描述符。

s多路复用的主要目的elect目前几乎在所有的平台上支持,其良好跨linux平台支持也是它的一多路复用个优点。selelinuxct的一个缺点在于单个进程能够监视的文件描述linux系统安装符的数量存在最大限制,在32位机器上机默认1024个,64位默认2048,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低,具体数目可以用命令察看(cat /proc/sys/fs/file-max)。此外对socket是线性扫描,即轮询,效率较低: 仅知道有I/O事件发生,却不知是哪几个流,只会无差异轮询所有流,找出能读数据或写数据的流进行操作。同时处理的流越多,无差别轮询时间越长 - O(n)。

2、poll

不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。

struct pollfd {
int fd; /* file descriptor */
short events; /* requested events to watch */
short revents; /* returned events witnessed */
};

pollfd结构包系统/运维含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后系统/运维性能系统运维工程师面试问题及答案也是会下降)。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。

从上面看,select和poll都需要在返回后,​​通过遍历文件描述符来获取已经就绪的多路复用socket​​。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线段描述符性下降。

poll和select同样存在一个缺点就是,包含大量文件描述系统运维包括哪些内容符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符描述符合中国山水画的意境追求是否就绪,它的多路复用不包括开销随着文件描述文件描述符符数量的增加而线性文件描述符是什么增大。

3、epoll

epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于selec多路复用技术有哪几种t和poll来说,epoll更加灵活,没有描述符限制。epol多路复用是指l使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

epoll模型修改主动轮询为被系统运维工资一般多少动通知,当有事件发生时,被动接收通知。所以epoll模型注册套接字后,主程序可做其他事情,当事件发生时,接收到通知后再去处理。可理解为event poll,epoll会把哪个流发生哪种I/O事件通知我们。所以epoll是事件驱动(每个事件关联fd),此时我们对系统运维工作内容这些流的操作都linux操作系统基础知识是有意义的。复杂度也降到O(1)。