為什麼epoll比select效率更高(Why is epoll faster than select)?
Why is epoll faster than select?
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.
比如說一個典型的伺服器需要處理200個連線。每個連線需要讀或寫資料,然後進入等待狀態,直到被喚醒可以繼續做下一步。
程序在等待狀態時候,當這200個連線中任何一個接受到資料後,該程序的等待狀態將會被打斷。
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.
對select來說,核心需要為把200個程序連線新增到對應的200個等待佇列中。核心需要一個“thunk”來連線程序和等待佇列。
當程序在等待佇列中喚醒時候,需要把程序中等待佇列中移除,該程序對應的“thunk”也需要釋放掉。
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.
作為對比,epoll自己有一個等待佇列。所有的程序只需要一個等待佇列,只要一個“thunk”.
當程序喚醒時候,該程序只會從那一個“thunk”中移除。總共只需要有一個“thunk”釋放。
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.
要清楚,epoll socket會對這200連線建立連線,每個連線只建立一次。當每個連線移除時候,每個連線刪除一次。
作為對照,每次呼叫select 都必須將程序新增到每個被監視的套接字的等待佇列中。
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 is so that the socket activity itself notifies the process.