select、poll、epoll三者区别

select

      select 的参数类型 fd_set 没有将文件描述符和事件绑定,它仅仅是一个文件描述符集合,因此 select 需要提供 3 个这种类型的参数来分别传入和输出可读、可写及异常等事件。这一方面使得 select 不能处理更多类型的事件,另一方面由于内核对 fd_set 集合的在线修改,应用程序下次调用 select 前不得不重置这3个 fd_set 集合。

poll

      poll 把文件描述符和事件都定义其中,任何事件都被统一处理,从而使得编程接口简洁得多。并且内核每次修改的是 pollfd 结构体的 revents 成员,而 events 成员保持不变,因此下次调用 poll 时应用程序无须重置 pollfd 类型的事件集参数。由于每次 poll 调用都返回整个用户注册的事件集合(其中包括就绪的和未就绪的),所以应用程序索引就绪文件描述符的时间复杂度为 O(n)。

epoll

      epoll 则采用与 select 和 poll 完全不同的方式来管理用户注册的事件。它在内核中维护一个事件表,并提供了一个独立的系统调用 epoll_ctl 来控制往其中添加、删除、修改事件。这样,每次 epoll_wait 调用都直接从该内核事件表中取得用户注册的事件,而无须反复从用户空间读入这些事件。epoll_wait 系统调用的 events 参数仅用来返回就绪的事件,这使得应用程序索引就绪的事件,这使得应用程序索引就绪文件描述符的时间复杂度达到 O(1)。

共同点:

     3 组系统调用都能同时监听多个文件描述符。它们将等待由 timeout 参数指定的超时时间,直到一个或者多个文件描述符上有事件发生时返回,返回值是就绪的文件描述符的数量。返回 0 表示没有事件发生。
     这3组函数都通过某种结构体变量来告诉内核监听哪些文件描述符上的哪些事件,并使用该结构体类型的参数来获取内核处理的结果。

不同点

     poll 和 epoll_wait 分别用 nfds 和 maxevents 参数指定最多监听多少个文件描述符和事件。poll 和 epoll 这两个数值都能达到系统允许打开的最大文件描述符数目,即65535。而 select 允许监听的最大文件描述符数量通常有限制。虽然用户可以修改这个限制,但这可能导致不可预期的后果。

     epoll 用户关注的事件直接保存到内核事件表中,每次 epoll_wait 不需要从用户空间向内核空间拷贝。select 每次都会重新设置事件,一调用 select 就会把用户空间的数据拷贝到内核空间,在内核空间修改。poll 每次添加事件添加到用户数组里面,poll 每次调用会把用户数组的数据全部重新拷贝到内核

     select 和 poll 都只能工作在 select 相对低效的 LT 模式,而 epoll 则可以工作在ET高效模式。并且 epoll 还支持 EPOLLONESHOT 事件。该事件能进一步减少可读、可写和异常等事件被触发的次数。

     epoll 内核实现比 select 和 poll 高效。select 和 poll 采用的都是轮询的方式,即每次调用都要扫描整个注册文件描述符集合,并将其中就绪的文件描述符返回给用户程序,因此它们检测就绪事件的算法的时间复杂度是 O(n)。

     epoll_wait 采用的是回调的方式。内核检测到就绪的文件描述符时,将触发回调函数,回调函数就将该文件描述符上对应的事件插入内核就绪事件队列。内核最后在适当的时机将该就绪事件队列中的内容拷贝到用户空间。因此 epoll_wait 无须轮询整个文件描述符集合来检测哪些事件已经就绪,其算法时间复杂度是 O(1)。

     但是,当活动连接比较多的时候,epoll_wait 的效率未必比 select 和 poll 高,因为此时回调函数被触发得过于频繁。所以活动连接较少的情况。epoll_wait 适用于连接数量多,但活动连接较少的情况。

                    系统调用 selectpollepoll
事件集合 用户通过 3 个参数分别传入感兴趣的可读、可写及异常等事件,内核通过对这些参数的在线修改来反馈其中的就绪事件。这使得用户每调用 seleet 都要重置这3个参数 统一处理所有事件类型,因此只需一个事件集参数,用户通过 pollfd.events 传入感兴睡的事件,内核通过修改 pollfd.revents 反馈其中就绪的事件 内核通过一个事件表直接管理用户感兴睡的所有事件。因此每次调用 epoll_wait 时,无须反复传入用户感兴趣的事件。epoll_wait 系统调用的参数 events 仅用来反馈就绪的事件
应用程序索引就绪文件描述符的时间复杂度O(n) O(n) O(1)
最大支持文件描述符数 一般有最大值限制 6553565535
工作模式 LT LT 支持 ET 高效模式
内核实现和工作效率 采用轮询方式来检测就绪事件,算法时间复杂度为 O(n) 采用轮询方式来检测就绪事件,算法时间复杂度为 O(n) 采用回调方式来检测就绪事件,算法时间复杂度为 O(1)
底层实现数组链表红黑树

     epoll 内核回调适用于:关注的文件描述符比较多,但是每次就绪的文件描述符很少
如果关注的文件描述符都,而且每次就绪的文件描述符也多 poll

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值