文章目錄
下面的例子來自知乎。 I/O多路複用技術(multiplexing)是什麼?
下面舉一個例子,模擬一個tcp服務器處理30個客戶socket。
假設你是一個老師,讓30個學生解答一道題目,然後檢查學生做的是否正確,你有下面幾個選擇:
(a)第一種選擇:按順序逐個檢查,先檢查A,然後是B,之後是C、D。。。這中間如果有一個學生卡主,全班都會被耽誤。
這種模式就好比,你用循環挨個處理socket,根本不具有併發能力。
(b)第二種選擇:你創建30個分身,每個分身檢查一個學生的答案是否正確。 這種類似於爲每一個用戶創建一個進程或者線程處理連接。
(c)第三種選擇,你站在講臺上等,誰解答完誰舉手。這時C、D舉手,表示他們解答問題完畢,你下去依次檢查C、D的答案,然後繼續回到講臺上等。此時E、A又舉手,然後去處理E和A。。。
這種就是IO複用模型
,Linux下的select
、poll
和epoll
就是幹這個的。將用戶socket對應的fd註冊進epoll
,然後epoll
幫你監聽哪些socket上有消息到達,這樣就避免了大量的無用操作。此時的socket應該採用非阻塞模式
。
這樣,整個過程只在調用select
、poll
、epoll
這些調用的時候纔會阻塞,收發客戶消息是不會阻塞的,整個進程或者線程就被充分利用起來,這就是事件驅動
,所謂的reactor模式
。
IO
分爲兩種:
磁盤IO
網絡IO
IO多路複用模型
:
多路:表示多個TCP
連接。
複用:表示公寓一個線程或進程。
優點:系統開銷小,不必尾貨過多的線程或進程。
IO多路複用
的核心是可以同時處理多個連接請求
,爲此使用了兩個系統調用,分別是:
select/poll/epoll
–模型機制:可以監視多個描述符(fd)
,一旦某個描述符就緒(讀/寫/異常)就能通知程序進行相應的讀寫操作。讀寫操作都是自己負責的,也即是阻塞的,所以本質上都是同步(堵塞)IO
。Redis
支持這三種機制,默認使用epoll機制
。recvfrom
–接收數據。
而blocking IO
只調用了recvfrom
,所以在連接數不高的情況下,blocking IO
的性能不一定比IO多路複用
差。
IO多路複用的三種實現機制:
- select機制。
- poll機制。
- epoll機制。
具體情況見 IO多路複用:Redis中經典的Reactor設計模式
[1] I/O多路複用技術(multiplexing)是什麼?
[2] IO多路複用:Redis中經典的Reactor設計模式