epoll為什麼如此高效

2021-10-08 14:31:56 字數 1305 閱讀 3335

在我的博文《linux的select poll epoll的io多路復用》中介紹過:

level-triggered即條件觸發,只要滿足事件的條件,比如有資料需要讀,就一直不斷地把這個事件傳遞給使用者;

edge-triggered即邊緣觸發,只有第一次滿足條件的時候才觸發,之後就不會再傳遞同樣的事件了。一般來說邊緣觸發的效率比條件觸發的效率要高。

從上文的博文中可以看出,在 ep_send_events_proc 函式的最後,針對 level-triggered 情況,當前的 epoll_item 物件被重新加到 eventpoll 的就緒列表中,這樣在下一次 epoll_wait 呼叫時,這些 epoll_item 物件就會被重新處理。又由於,在最終拷貝到使用者空間有效事件列表中之前,會呼叫對應檔案的 poll 方法,以確定這個事件是不是依然有效。所以,如果使用者空間程式已經處理掉該事件,就不會被再次通知,但是會導致epoll_wait空跑一次;如果沒有處理,意味著該事件依然有效,就會被再次通知。

這就是為什麼我們說edge-triggered效率會高一些。

1、poll/select 先將要監聽的 fd 從使用者空間拷貝到核心空間, 然後在核心空間裡面進行處理之後,再拷貝給使用者空間。這裡就涉及到核心空間申請記憶體,釋放記憶體等等過程,這在大量 fd 情況下,是非常耗時的。而 epoll 維護了乙個紅黑樹,通過對這棵黑紅樹進行操作,可以避免大量的記憶體申請和釋放的操作,而且查詢速度非常快。

2、select/poll 從休眠中被喚醒時(某個描述符發生事件,時間片到,發生訊號),核心就會遍歷內部的 list 去檢查到底是哪乙個事件到達,並沒有像 epoll 一樣, 通過 fd 直接關聯 eventpoll 物件,快速地把 fd 直接加入到 eventpoll 的就緒列表中。

3、poll/select返回時,需要遍歷fd集合,以查詢哪些fd上面有事件發生,而epoll直接返回有事件的集合。

補充一下epoll事件的觸發時機

1.水平觸發的時機

對於讀操作,只要緩衝內容不為空,lt模式返回讀就緒;

對於寫操作,只要緩衝區還不滿,lt模式會返回寫就緒。

2.邊緣觸發的時機

對於讀操作

當緩衝區由不可讀變為可讀的時候,即緩衝區由空變為不空的時候;

當有新資料到達時,即緩衝區中的待讀資料變多的時候;

當緩衝區有資料可讀,且應用程序對相應的描述符進行epoll_ctl_mod 修改epollin事件時。

對於寫操作

當緩衝區由不可寫變為可寫時;

當有舊資料被傳送走,即緩衝區中的內容變少的時候;

當緩衝區有空間可寫,且應用程序對相應的描述符進行epoll_ctl_mod 修改epollout事件時。

從I O復用談epoll為什麼高效

很多人提到網路就說epoll,認為epoll效率是最高的。單純的這麼認為,其實有失偏頗。epoll固然高效,可是它是怎麼做到高效的,它到底比select或poll優異在哪兒?我們通過呼叫流程來簡單分析下。首先以select為例 poll類似 看下其呼叫過程 1.選擇想要處理的套接字,通過介面fd s...

epoll為什麼快

epoll是linux下的一種i o多路復用的操作方式,是event poll的意思 i o多路復用,舉個栗子,在酒吧,乙個服務員,10個顧客在喝酒,服務員有這麼幾種服務方式 服務員從第乙個顧客開始問,你要酒嗎,再問第二個,你要酒嗎,依次問下去,問完一圈,再從頭開始,服務員就是不停的在bbb,要酒嗎...

為什麼需要epoll

首先我們來定義流的概念,乙個流可以是檔案,socket,pipe等等可以進行i o操作的核心物件。不管是檔案,還是套接字,還是管道,我們都可以把他們看作流。之後我們來討論i o的操作,通過read,我們可以從流中讀入資料 通過write,我們可以往流寫入資料。現在假定乙個情形,我們需要從流中讀資料,...