I/O多路複用機制(Epoll)

IO多路複用之select、poll、epoll詳解

 

I/O多路複用機制(Epoll) 

多路I/O複用模型是利用 select、poll、epoll 可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前線程阻塞掉。當有一個或多個流有 I/O事件時,就從阻塞態中喚醒,於是程序就會輪詢一遍所有的流(epoll 是隻輪詢那些真正發出了事件的流)並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。 

 

這裏“多路”指的是多個網絡連接,“複用”指的是複用同一個線程。

採用多路 I/O 複用技術可以讓單個線程高效的處理多個連接請求(儘量減少網絡 IO 的時間消耗),且 Redis在內存中操作數據的速度非常快,也就是說內存內的操作不會成爲影響Redis性能的瓶頸,主要由以上幾點造就了 Redis 具有很高的吞吐量。

 

(1)網絡IO都是通過Socket實現,Server在某一個端口持續監聽,客戶端通過Socket(IP+Port)與服務器建立連接(ServerSocket.accept),成功建立連接之後,就可以使用Socket中封裝的InputStream和OutputStream進行IO交互了。針對每個客戶端,Server都會創建一個新線程專門用於處理 

 

(2) 默認情況下,網絡IO是阻塞模式,即服務器線程在數據到來之前處於【阻塞】狀態,等到數據到達,會自動喚醒服務器線程,着手進行處理。阻塞模式下,一個線程只能處理一個流的IO事件 

 

(3) 爲了提升服務器線程處理效率,有以下三種思路

 

a、非阻塞【忙輪詢】:採用死循環方式輪詢每一個流,如果有IO事件就處理,這樣可以使得一個線程可以處理多個流,但是效率不高,容易導致CPU空轉

 

b、Select代理(無差別輪詢):可以觀察多個流的IO事件,如果所有流都沒有IO事件,則將線程進入阻塞狀態,如果有一個或多個發生了IO事件,則喚醒線程去處理。但是還是得遍歷所有的流,才能找出哪些流需要處理。如果流個數爲N,則時間複雜度爲O(N)

 

c、Epoll代理:Select代理有一個缺點,線程在被喚醒後輪詢所有的Stream,還是存在無效操作。 Epoll會哪個流發生了怎樣的I/O事件通知處理線程,因此對這些流的操作都是有意義的,複雜度降低到了O(1)

 

 

多路複用機制打一個比方:



 

下面類比到真實的redis線程模型,如圖

所示多路複用:

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章