I/O多路複用機制(Epoll)
ofollow,noindex"> 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)