epoll简介

epoll和poll、select执行差不多的任务,都是监听在多个文件描述符(file descriptor)是否有I/O就绪,但是执行的方式有很大的差别,特别是epoll和poll、select之间的差别是最大的。

epoll、poll、select

select

select是采用的轮询的方式来检测文件描述符(file descriptor)上的I/O是否就绪的,这种方式的时间复杂度是跟随者文件描述符的个数而成线性增加的,所以时间复杂度是0(n),当然也可以不轮询,一直阻塞下去或者是设置一个等待超时,还有就是select针对每一种事件(读、写..)都有一个数组会占据额外的空间,而且在内核中对select支持的文件描述符数量有一定的限制,所以如果要想select支持。

poll

是select的变种,通过结构体来封装文件描述符的事件

struct pollfd {
               int   fd;         /* file descriptor */
               short events;     /* requested events 需要监听的事件 */
               short revents;    /* returned events 监听返回的事件*/
           };
  • 1

这样就可以避免select的分别对读写事件分配内存空间了,可以对时间进行统一的处理,当然还有其他的更好的改进。

epoll

epoll又是在poll的基础上进行改进的,epoll在poll的基础上增加了两种事件的触发方式: Level-triggered(水平触发) 和 edge-triggered(边沿触发),这两种方式有很大的区别,不同的设置方式对I/O的操作方式也不同,epoll 的Level-triggered(水平触发)模式和poll的处理方式是差不多的,但是epoll的edge-triggered(边沿触发)模式就不太一样,所以I/O的处理方式也是不一样的:其中主要的不同是epoll_wait返回的方式不太一样,Level-triggered(水平触发)模式的epoll_wait返回多次是只要是可读都会返回fd(文件描述符);但是edge-triggered(边沿触发)模式只有在fd(文件描述符)从没有就绪——>就绪的时候epoll_wait返回一次,所以这就要求在edge-triggered(边沿触发)模式下应使用非阻塞的文件描述符,以及需要epoll_wait返回的时候一次性的将数据全部读完或者写完直到EAGAIN