为什么epoll比select更快? [英] Why is epoll faster than select?
问题描述
我看到了很多比较,这些比较表明select必须遍历fd列表,这很慢.但是为什么epoll不必这样做?
对此有很多误传,但真正的原因是这样:
一个典型的服务器可能正在处理200个连接.它将为需要写入或读取数据的每个连接提供服务,然后将需要等待直到有更多工作要做.在等待期间,如果在这200个连接中的任何一个上接收到数据,都需要中断它.
使用select
,内核必须将进程添加到200个等待列表中,每个连接一个.为此,它需要"thunk"将流程附加到等待列表.当该过程最终唤醒时,需要将其从所有200个等待列表中删除,并且所有这些thunk都需要释放.
相比之下,与epoll
相比,epoll
套接字本身具有一个等待列表.仅需使用一个进程,就可以将进程仅放在一个等待列表上.进程唤醒后,只需要将其从一个等待列表中删除,并且只需释放一个thunk.
为清楚起见,对于epoll
,epoll
套接字本身必须连接到这200个连接中的每一个.但是,对于每个连接,首先要接受一次.对于每个连接,将其拆除时,将其拆下一次.相比之下,每次对select
的阻塞调用都必须将进程添加到每个要监视的套接字的等待队列中.
select
,最大的开销来自检查没有活动的套接字是否有任何活动.使用epoll
,不需要检查没有活动的套接字,因为如果它们确实有活动,则在发生该活动时,它们会通知epoll
套接字.从某种意义上讲,select
每次调用select
时都会轮询每个套接字,以查看epoll
绑定它时是否有任何活动,以便套接字活动本身通知该进程.I have seen a lot of comparisons which says select have to walk through the fd list, and this is slow. But why doesn't epoll have to do this?
There's a lot of misinformation about this, but the real reason is this:
A typical server might be dealing with, say, 200 connections. It will service every connection that needs to have data written or read and then it will need to wait until there's more work to do. While it's waiting, it needs to be interrupted if data is received on any of those 200 connections.
With select
, the kernel has to add the process to 200 wait lists, one for each connection. To do this, it needs a "thunk" to attach the process to the wait list. When the process finally does wake up, it needs to be removed from all 200 wait lists and all those thunks need to be freed.
By contrast, with epoll
, the epoll
socket itself has a wait list. The process needs to be put on only that one wait list using only one thunk. When the process wakes up, it needs to be removed from only one wait list and only one thunk needs to be freed.
To be clear, with epoll
, the epoll
socket itself has to be attached to each of those 200 connections. But this is done once, for each connection, when it is accepted in the first place. And this is torn down once, for each connection, when it is removed. By contrast, each call to select
that blocks must add the process to every wait queue for every socket being monitored.
Ironically, with select
, the largest cost comes from checking if sockets that have had no activity have had any activity. With epoll
, there is no need to check sockets that have had no activity because if they did have activity, they would have informed the epoll
socket when that activity happened. In a sense, select
polls each socket each time you call select
to see if there's any activity while epoll
rigs it so that the socket activity itself notifies the process.
这篇关于为什么epoll比select更快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!