select、poll和epoll

1、对于select和poll来说,所有文件描述符都是在用户态被加入其文件描述符集合的,每次调用都需要将整个集合拷贝到内核态;epoll则将整个文件描述符集合维护在内核态,每次添加文件描述符的时候都需要执行一个系统调用。系统调用的开销是很大的,而且在有很多短期活跃连接的情况下,epoll可能会慢于select和poll由于这些大量的系统调用开销。

2、select使用线性表描述文件描述符集合,文件描述符有上限;poll使用链表来描述;epoll底层通过红黑树来描述,并且维护一个ready list,将事件表中已经就绪的事件添加到这里,在使用epoll_wait调用时,仅观察这个list中有没有数据即可。
疑问:select用的不是bitmap吗?

3、select和poll的最大开销来自内核判断是否有文件描述符就绪这一过程:每次执行select或poll调用时,它们会采用遍历的方式,遍历整个文件描述符集合去判断各个文件描述符是否有活动;epoll则不需要去以这种方式检查,当有活动产生时,会自动触发epoll回调函数通知epoll文件描述符,然后内核将这些就绪的文件描述符放到之前提到的ready list中等待epoll_wait调用后被处理。

4、select和poll都只能工作在相对低效的LT模式下,而epoll同时支持LT和ET模式。

综上,当监测的fd数量较小,且各个fd都很活跃的情况下,建议使用select和poll;当监听的fd数量较多,且单位时间仅部分fd活跃的情况下,使用epoll会明显提升性能。

总结:select和poll是要进行一次从用户到内核的拷贝,而且遍历一遍O(N)。而epoll则值一直在内核,而且采用了红黑树的设计,查询复杂度降到了O(1);
但并不是什么时候select都不好,在短期活跃的情况下,epoll可能因为系统调用相对慢。

Epoll对文件操作符的操作有两种模式:LT(电平触发)和ET(边缘触发),二者的区别在于当你调用epoll_wait的时候内核里面发生了什么:

LT(电平触发):类似select,LT会去遍历在epoll事件表中每个文件描述符,来观察是否有我们感兴趣的事件发生,如果有(触发了该文件描述符上的回调函数),epoll_wait就会以非阻塞的方式返回。应用程序可以不立即处理该事件。若该epoll事件没有被处理完(没有返回EWOULDBLOCK),该事件还会被后续的epoll_wait再次触发。

ET(边缘触发):ET在发现有我们感兴趣的事件发生后,立即返回,并且sleep这一事件的epoll_wait,不管该事件有没有结束。

特殊的EPOLLONESHOT
一个线程读取某个socket上数据后开始处理数据,在处理过程中,该socket上又有新数据可读,此时另一个线程被唤醒读取,此时出现两个线程处理同一个socket。
期望获得的是一个socket连接在任一时刻都智能通被一个线程处理,通过epoll_ctl对该文件描述符注册epolloneshot时间,一个线程处理socket后,其他线程将无法处理,只有当该线程处理完,通过epoll_ctl重置epolloneshot事件。
一个线程读取某个socket上的数据后开始处理数据,在处理过程中该socket上又有新数据可读,此时另一个线程被唤醒读取,此时出现两个线程处理同一个socket

我们期望的是一个socket连接在任一时刻都只被一个线程处理,通过epoll_ctl对该文件描述符注册epolloneshot事件,一个线程处理socket时,其他线程将无法处理,当该线程处理完后,需要通过epoll_ctl重置epolloneshot事件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值