動圖瞭解I

啥叫I/O多路複用? epoll又是個什麼東西? 你或許看過很多文章,但是還是感覺雲裡霧裡的,今天,我們拋開文字,釋放動圖,或許你就理解了。

I/O多路複用

通常的一次的請求結果如下圖所示:

動圖瞭解I/O多路複用

但是,服務器往往不會只處理一次請求,往往是多個請求,這一個請求,這時候每來一個請求,就會生成一個進程或線程。

動圖瞭解I/O多路複用

在這些請求線程或者進程中,大部分都處於等待階段,只有少部分是接收數據。這樣一來,非常耗費資源,而且這些線程或者進程的管理,也是個事兒。

動圖瞭解I/O多路複用

於是,有人想到一個辦法:我們只用一個線程或者進程來和系統內核打交道,並想辦法把每個應用的I/O流狀態記錄下來,一有響應變及時返回給相應的應用。

動圖瞭解I/O多路複用

或者下圖:

動圖瞭解I/O多路複用

select、poll、epoll

select, poll, epoll 都是I/O多路複用的具體實現,他們出現是有先後順序的。

select是第一個實現 (1983 左右在BSD裡面實現的)。

select 被實現後,發現諸多問題,然後1997年實現了poll,對select進行了改進,select和poll是很類似的。

再後來,2002做出重大改進實現了epoll。

epoll和 select/poll 有著很大的不同:

例如:select/poll的處理流程如下:

動圖瞭解I/O多路複用

而epoll的處理流程如下:

動圖瞭解I/O多路複用

這樣,就無需遍歷成千上萬個消息列表了,直接可以定位哪個socket有數據。

那麼,這是如何實現的呢?

早期的時候 epoll的實現是一個哈希表,但是後來由於佔用空間比較大,改為了紅黑樹和鏈表。

動圖瞭解I/O多路複用

其中鏈表中全部為活躍的鏈接,紅黑樹中放的是所有事件。兩部分各司其職。 這樣一來,當收到內核的數據時,只需遍歷鏈表中的數據就行了,而註冊read事件或者write事件的時候,向紅黑樹中記錄。

結果導致:

  • 創建\\修改\\刪除消息效率非常高:O(logN)。
  • 獲取活躍鏈接也非常快,因為在一個時間內,大部分是不活躍的鏈接,活躍的鏈接是少數,只需要遍歷少數活躍的鏈接就好了
動圖瞭解I/O多路複用


分享到:


相關文章: