select和epoll

select和epoll都是监控文件句柄的IO动作是否准备就绪的实现方式,区别在于才大多数情况下后者比前者更加高效。之所以造成这种情况,是由于两者的实现机制不同。

1 select监控句柄IO动作的方式

select内部维护了一个数组,这个数据中记录的都是文件句柄。select通过遍历这个数据,来监控有哪些句柄的IO动作已经准备就绪。

1 在遍历数组过程中,如果发现有句柄准备就绪,那么就会返回,通知程序已经有句柄准备就绪,可供读写,但是这里并没有告诉程序是哪个句柄准备就绪,要想获取,需要程序再次遍历这个数组;

2 如果select遍历完真个数组,都没有就绪的句柄,那么select进程就会沉睡

3 在select陷入沉睡的过程中,当数组中的句柄有准备就绪的话,就会去唤醒select,select唤醒之后,会再次遍历数组,找寻就绪的句柄

通过以上步骤,可以发现,基于select来监控句柄的状态,其时间复杂度是O(n),这还不算其等待时间

另外,linux规定单进程能够监控的句柄最多是1024个,这也就意味着当需要监控超过1024个句柄时,就需要多个select进程,而这种情况又是非常常见的,如Web服务器需要维护数万级别的Socket连接,因此,在这种情况下select的性能比较低下

2 epoll

epoll完美规避了select所存在的问题

1 首先,epoll为了监控句柄,内部并非维护一个数组,而是维护了一个链表,链表大小没有限制,因此一个epoll进程可以监控远远超过1024个句柄。

2 这个链表是按照红黑树的数据结构进行存储的,这就意味着查找和删除里面的句柄非常迅速

3 除此之外,epoll内部还维护了额外的一个链表,用于记录准备就绪的句柄。当程序调用epoll_wait时,只需要检查这个链表是否为空即可,不为空,即返回这个链表,里面就是所有准备就绪的句柄。

通过上面可以看出,首先epoll的单进程既可以监控大规模数量的句柄,然后,epoll监控的是一个红黑树,这移除一个句柄和增加一个监控句柄非常容易,最后,程序获取准备就绪的句柄时,无须遍历所有监控句柄,只需要调用epoll_wait就可获取所有准备就绪的句柄,因此非常高效。

但是,需要注意的是,并非所有情况下,epoll效率都比select高,当监控的句柄中每次查询都是绝大部分处于就绪状态的话,那么使用select反而比epoll效率高,这事因为如果监控的绝大多数句柄都处于就绪状态的话,epoll的就绪链表就会很大,寻找这个链表的效率就会很低

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值