select poll epoll之間的區別

2022-03-20 05:07:55 字數 1676 閱讀 2084

1、select poll每次迴圈呼叫時都需要將檔案描述符和事件拷貝到核心空間,epoll只需要拷貝一次;

(這種情況在對於描述符數量不大的情況下還可以,但是當描述符的數量達到十幾萬甚至上百萬的時候,他們的效率就會急速降低,因為每一次輪詢都需要將這些所有的socket描述符從使用者態拷貝到核心態,會造成大量的浪費和資源開銷)

2、select poll每次返回後,需要遍歷所有描述符才能找到就緒的,因此它倆的時間複雜度為o(n),而epoll只需要o(1);

3、select poll核心通過輪詢的方式完成,時間複雜度為o(n),而epoll是在每個檔案描述符上設定**函式,時間複雜度為o(1)。

(與select相比poll沒有太多的區別,唯一的改進是使用了鍊錶來儲存fd,使得能夠監聽的數量遠遠超過了1024,但是對於將使用者資料拷貝到核心空間,線性遍歷fd這兩個並沒有太大的改變)

epoll的底層實現

利用sys_epoll_create()建立核心事件表,在sys_epoll_creat()裡面建立了struct eventpoll結構體,其中包括兩個成員:

就緒佇列struct list_head rdlist,用來存放有就緒事件的描述符;

紅黑樹struct rb_root rbr,作為核心事件表,用來收集描述符;

每乙個epoll物件都有乙個獨立的eventpoll結構體,用於存放通過epoll_ctl方法向epoll物件中新增進來的事件。這些事件都會通過ep_instert掛載到紅黑樹上,這樣重複新增的事件就可以通過紅黑樹而高效的識別出來;

而所有新增到epoll中的事件都會與驅動程式建立**關係,當相應的事件發生時,會呼叫ep_poll_callback這個**方法,它會將發生的事件新增到rdlist中;

在epoll中,對於每乙個事件,都會建立乙個epitem結構體,它裡面包括:

紅黑樹節點

rdlist節點

事件控制代碼資訊

乙個指向其所屬的eventpoll物件的指標

期待發生的事件型別

當呼叫epoll_wait檢查是否有事件發生時,只需要檢查eventpoll物件中的rdlist中是否有epitem元素即可。如果rdlist不為空,則把事件複製到使用者態,同時將事件數量返回給使用者;如果為空,就等待直到超時

通過分析可知:通過紅黑樹和雙鏈表資料結構,並結合**機制,造就了epoll的高效;

epoll的工作模式et和lt

et模式是高速模式,叫做邊緣觸發模式,lt模式是預設模式,叫做水平觸發模式;

兩種工作模式的區別:

et模式:如果乙個描述符上有資料到達,然後讀取這個描述符上的資料,如果沒有將資料讀取完,當下次epoll_wait返回的時候這個描述符中的資料就再也讀取不到了;

lt模式:如果對乙個描述符的資料沒有讀取完成,那麼下次當epoll_wait返回的時候會繼續觸發,也就可以繼續獲取到這個描述符,從而能夠接著讀;

實現方式:

當乙個socket描述符的中斷事件發生,核心會將資料從網絡卡複製到核心,同時將1socket描述符插入到rddlist中,如果此時呼叫了epoll_wait會把rdlist中就緒的socket描述符複製到使用者空間,然後清理掉這個rdlist中的資料,最後epoll_wait還會再次檢查這些socket描述符。如果是工作在lt模式下,並且這些socket描述符上還有資料沒有讀取完,那麼lt就會再次把沒有讀完的socket描述符放入到rdlist中,所以再次呼叫epoll_wait的時候會再次觸發。

select poll epoll學習筆記

io多路復用,網路程式設計。io模型 阻塞式io模型 非阻塞式io模型,需要輪詢核心,較少使用 io復用模型,阻塞於select 訊號驅動式io模型 核心通知使用者程序何時可以啟動乙個io操作 非同步io模型 核心通知使用者程序操作何時完成。posix標準 可移植作業系統介面,ieee為各種在uni...

select poll epoll事件驅動

一直用select,沒有使用poll和epoll,近來需要使用epoll。以前面試時,有人問過我,我也簡單作答。現在寫一下我的理解。三者區別 select 監聽的檔案描述符有限制,linux系統預設是1024 poll 和select差不多,比select優越的地方是監聽的檔案描述符個數可以不限 e...

select poll epoll模型對比

select poll epoll模型對比 先說select 1.socket數量限制 該模式可操作的socket數由fd setsize決定,核心預設32 32 1024.2.操作限制 通過遍歷fd setsize個socket來完成排程,不管哪個socket是活躍的,都遍歷一遍.後說poll 1...