程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

epoll相比select为什么更高效?(为什么epoll比select更加高效)

balukai 2025-03-26 09:50:42 文章精选 5 ℃

#秋日生活打卡季#

1.select和epoll有什么不同?

不同之处一:

select可以监听文件描述符是有限的,由FD_SETSIZE设置,默认是1024,可以通过修改这个宏来增加可监听文件描述符的个数,但资料同时指出这样修改将导致不可预期的效果。

epoll可监听的文件描述符的个数为进程可打开的文件的个数。

不同之处二:

select中,当有事件就绪时,内核修改参数以通知用户,用户需要遍历所有的fd判断是哪个fd就绪,应用程序索引就绪文件描述符的时间复杂度是O(n),IO效率随着监听的fd的数目增加而线性下降。

epoll中注册了回调函数,当有就绪事件发生的时候,设备驱动程序调用回调函数,将就绪的fd添加到rdllist中,调用epoll_wait时,将rdllist上就绪的fd发送给用户,应用程序索引就绪文件描述符的时间复杂度是O(1),IO效率与fd的数目无关。

不同之处三:

epoll支持ET模式,当内核将该事件通知给用户后,用户必须立即处理,这样就减少了可读、可写、异常事件被触发的次数。

select只能工作在相对较低效的LT模式。

2.为什么epoll比select高效?

在select中,用户通过fd_set_bits将感兴趣的事件通知内核,内核要将用户感兴趣的事件拷贝到内核空间,并为每个fd分配一个poll_table_page结构体,用来监听该fd上是否有就绪事件。如果有就绪事件,内核修改用户传进来的fd_set_bits告知用户事件有就绪事件发生,删除分配的poll_table_page结构体。应用程序要遍历所有的fd找到就绪的fd。因为fd_set_bits已经被内核修改,下次调用select之前必须重置fd_set_bits,然后重新传给内核,内核重新拷贝一份,重新分配结构体。

在epoll中,在调用epoll_ctl时,已经将用户感兴趣的事件传给了内核,内核会维持一个内核事件表,记录用户感兴趣的事件,就绪事件发生时,驱动设备调用回调函数将就绪的fd挂到rdllist上。用户调用epoll_wait时,将rdllist上就绪的文件描述符发送给用户。此时发送给用户的都是就绪的fd。

3.不论哪种情况,epoll永远比select高效吗?

不一定!

epoll适用于连接较多,活动数量较少的情况。

1. epoll为了实现返回就绪的文件描述符,维护了一个红黑树和好多个等待队列,内核开销很大。如果此时监听了很少的文件描述符,底层的开销会得不偿失;

2.epoll中注册了回调函数,当有事件发生时,服务器设备驱动调用回调函数将就绪的fd挂在rdllist上,如果有很多的活动,同一时间需要调用的回调函数数量太多,服务器压力太大。

select适用于连接较少的情况。

当select上监听的fd数量较少,内核通知用户现在有就绪事件发生,应用程序判断当前是哪个fd就绪所消耗的时间复杂度就会大大减小。

最近发表
标签列表