epoll,select,poll的区别

注:看到一篇讲解epoll原理的文章,写得非常详细,建议阅读:epoll实现原理

之前分别记录了epoll(并发程序设计3:多路IO复用技术(2)),select和poll(并发程序设计2:多路IO复用技术(1))的用法,本节比较一下它们各自的特点。

1. select和poll的不同

 

(1) select和poll的原理和用法基本上是一样的,其内部实现机制也差不多,主要区别在于注册的结构体不一样。select采用fd_set结构体,每次文件描述符发生改变,相应的fd_set结构体就被改变了,因此在每次调用select之前要重置fd_set结构体。而poll采用的pollfd数组,结构为:

struct pollfd
{
    int fd;
    short events;
    short revents;
}

注册的事件和发生的事件分别用events和revents表示,所以只需置一次pollfd数组。简言之,select每次都要重置fd_set,poll只需要置一次pollfd结构体

(2) poll可以注册的事件类型没有限制,而select注册事件有限制(FD_SETSIZE宏定义的值,32位机通常是1024,64位机通常是2048)。

2. select(poll)和epoll的区别

select和epoll实现机制不一样。下面的图说明了select的原理

 

epoll与select的主要不同就在于:

(1) epoll只在初始时完成一次文件描述符的注册,拷贝到内核,即在调用epoll_ctl()指定EPOLL_CTL_ADD时;

(2) epoll在内核态采用回调函数的形式,只有相应的文件描述符发生变化,回调函数才被调用,将发生变化的描述符集中到新的epoll_event的数组中,时间复杂度O(1);

(3) 返回的epoll_event数组只包含发生变换的文件描述符,所以不用遍历所有的文件描述符,时间复杂度O(1)。

详细的比较如下表:

系统调用 select poll epoll
事件集合

三个fd_set数组,分别记录可读,可写和异常事件,

内核修改fd_set数组来通知状态改变。每次调用之

前都要重置fd_set数组。

一个pollfd结构体数组,统一记

录所有的可读,可写及异常事件,

通过fdarray[i].events注

册事件,fdarray[i].revents通知事件改变

直接调用epoll_ctl将事件类型和描述

符添加到内核,只需要一次添加即可

应用程序索引就绪文件描述符的事件复杂度 O(n) O(n) O(1)
最大支持文件描述符数量 有限制 65535 65535
工作模式 LT LT LT/ET(条件触发/边缘触发)
内核实现方式及时间复杂度 轮询检测就绪事件O(n) 轮询检测就绪事件O(n) 回调函数形式检测就绪事件O(1)

 

参考博客:

(1)select,poll,epoll的区别及函数原型

(2)select,poll,epoll区别总结

 

posted @ 2020-05-19 13:31  晨枫1  阅读(2543)  评论(0编辑  收藏  举报