I O多路復用

2022-06-18 21:42:22 字數 1832 閱讀 7847

i/o多路復用有很多種實現。在linux上,2.4核心前主要是select和poll,自linux 2.6核心正式引入epoll以來,epoll已經成為了目前實現高效能網路伺服器的必備技術。儘管他們的使用方法不盡相同,但是本質上卻沒有什麼區別。本文將重點**將放在epoll的實現與使用詳解。

高併發的核心解決方案是1個執行緒處理所有連線的「等待訊息準備好」,這一點上epoll和select是無爭議的。但select預估錯誤了一件事,當數十萬併發連線存在時,可能每一毫秒只有數百個活躍的連線,同時其餘數十萬連線在這一毫秒是非活躍的。select的使用方法是這樣的:

返回的活躍連線 ==select(全部待監控的連線)。

什麼時候會呼叫select方法呢?在你認為需要找出有報文到達的活躍連線時,就應該呼叫。所以,呼叫select在高併發時是會被頻繁呼叫的。這樣,這個頻繁呼叫的方法就很有必要看看它是否有效率,因為,它的輕微效率損失都會被「頻繁」二字所放大。它有效率損失嗎?顯而易見,全部待監控連線是數以十萬計的,返回的只是數百個活躍連線,這本身就是無效率的表現。被放大後就會發現,處理併發上萬個連線時,select就完全力不從心了。

此外,在linux核心中,select所用到的fd_set是有限的,即核心中有個引數__fd_setsize定義了每個fd_set的控制代碼個數。

其次,核心中實現 select是用輪詢方法,即每次檢測都會遍歷所有fd_set中的控制代碼,顯然,select函式執行時間與fd_set中的控制代碼個數有乙個比例關係,即 select要檢測的控制代碼數越多就會越費時。看到這裡,您可能要要問了,你為什麼不提poll?筆者認為select與poll在內部機制方面並沒有太大的差異。相比於select機制,poll只是取消了最大監控檔案描述符數限制,並沒有從根本上解決select存在的問題。

當併發連線為較小時,select與epoll似乎並無多少差距。可是當併發連線上來以後,select就顯得力不從心了。

epoll精巧的使用了3個方法來實現select方法要做的事:

新建epoll描述符==epoll_create()

epoll_ctrl(epoll描述符,新增或者刪除所有待監控的連線)

返回的活躍連線 ==epoll_wait( epoll描述符 )

與select相比,epoll分清了頻繁呼叫和不頻繁呼叫的操作。例如,epoll_ctrl是不太頻繁呼叫的,而epoll_wait是非常頻繁呼叫的。這時,epoll_wait卻幾乎沒有入參,這比select的效率高出一大截,而且,它也不會隨著併發連線的增加使得入參越發多起來,導致核心執行效率下降。

要深刻理解epoll,首先得了解epoll的三大關鍵要素:mmap、紅黑樹、鍊錶

epoll是通過核心與使用者空間mmap同一塊記憶體實現的。mmap將使用者空間的一塊位址和核心空間的一塊位址同時對映到相同的一塊物理記憶體位址(不管是使用者空間還是核心空間都是虛擬位址,最終要通過位址對映對映到實體地址),使得這塊物理記憶體對核心和對使用者均可見,減少使用者態和核心態之間的資料交換。核心可以直接看到epoll監聽的控制代碼,效率高。

紅黑樹將儲存epoll所監聽的套接字。上面mmap出來的記憶體如何儲存epoll所監聽的套接字,必然也得有一套資料結構,epoll在實現上採用紅黑樹去儲存所有套接字,當新增或者刪除乙個套接字時(epoll_ctl),都在紅黑樹上去處理,紅黑樹本身插入和刪除效能比較好,時間複雜度o(logn)。

需要注意的是:epoll並不是在所有的應用場景都會比select和poll高很多。尤其是當活動連線比較多的時候,**函式被觸發得過於頻繁的時候,epoll的效率也會受到顯著影響!所以,epoll特別適用於連線數量多,但活動連線較少的情況。

參照:

I O多路復用

一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...

i o多路復用

最常見的i o多路復用就是 select poll epoll了,下面說說他們的一些特點和區別吧。select 可讀 可寫 異常三種檔案描述符集的申明和初始化。fd set readfds,writefds,exceptionfds fd zero readfds fd zero writefds ...

I O多路復用

我們都知道unix like 世界裡,一切皆檔案,而檔案是什麼呢?檔案就是一串二進位製流而已,不管socket,還是fifo 管道 終端,對我們來說,一切都是檔案,一切都是流。在資訊 交換的過程中,我們都是對這些流進行資料的收發操作,簡稱為i o操作 input and output 往流中讀出資料...