八、網路服務I/O模型
8.1、四種的I/O模型
在作業系統中,程序無法直接操作I/O裝置,其必須通過系統呼叫請求kernel來協助完成I/O動作,而核心會為每個I/O裝置維護一個buffer。程序與I/O之間的通訊模型如圖所示。
對於輸入而言,等待(wait)資料輸入至buffer需要時間,而從buffer複製(copy)資料至程序也需要時間。根據呼叫者與被呼叫者的不同就有四種I/0模型。
呼叫者處理措施: 阻塞:程序發起I/O呼叫, 未完成之前,當前程序會被掛起; 非阻塞:程序發起I/O呼叫,被呼叫函式完成之前不會阻塞當前程序,而是立即返回; 被呼叫者響應: 同步:程序發起一個過程呼叫(功能、函式)呼叫後,在沒得到結果之前,該呼叫將不會返回; |
8.2、五種網路服務I/0模型
根據等待模式不同,I/O動作可分為五種模式:
同步阻塞:程序會一直阻塞,直到資料拷貝完成。
同步非阻塞:非阻塞IO通過程序反覆呼叫IO函式(多次系統呼叫,並馬上返回);在資料拷貝的過程中,程序是阻塞的。
I/O 複用:主要是select和epoll;對一個IO埠,兩次呼叫,兩次返回,比阻塞IO並沒有什麼優越性;關鍵是能實現同時對多個IO埠進行監聽。
非同步IO:資料拷貝的時候程序無需阻塞。
訊號驅動:兩次呼叫,兩次返回。
五種IO模型的比較:
8.3、select/poll/epoll
select
本質上是通過設定或者檢查存放fd標誌位的資料結構來進行下一步處理,但是單個程序可監視的fd數量被限制,即能監聽埠的大小有限。對socket進行掃描時是線性掃描,即採用輪詢的方法,效率較低,需要維護一個用來存放大量fd的資料結構,這樣會使得使用者空間和核心空間在傳遞該結構時複製開銷大。
#cat/proc/sys/fs/file-max#檢視可監聽fd的數量
poll
本質上和select沒有區別,它將使用者傳入的陣列拷貝到核心空間,然後查詢每個fd對應的裝置狀態,其沒有最大連線數的限制,原因是它是基於連結串列來儲存的,但是同樣有一個缺點:大量的fd的陣列被整體複製於使用者態和核心地址空間之間,而不管這樣的複製是不是有意。 poll還有一個特點是“水平觸發”,如果報告了fd後,沒有被處理,那麼下次poll時會再次報告該fd。
epoll
支援水平觸發和邊緣觸發,最大的特點在於邊緣觸發,它只告訴程序哪些fd剛剛變為就需態,並且只會通知一次。 使用“事件”的就緒通知方式,通過epoll_ctl註冊fd,一旦該fd就緒,核心就會採用類似callback的回撥機制來啟用該fd,epoll_wait便可以收到通知。
其優點是沒有最大併發連線的限制:能開啟的FD的上限遠大於1024(1G的記憶體上能監聽約10萬個埠)效率提升:非輪詢的方式,不會隨著FD數目的增加而效率下降;只有活躍可用的FD才會呼叫callback函式,即epoll最大的優點就在於它只管理“活躍”的連線,而跟連線總數無關。使用記憶體拷貝方式,利用mmap()檔案對映記憶體加速與核心空間的訊息傳遞;即epoll使用mmap減少複製開銷。
轉載於:https://blog.51cto.com/yinsuifeng/1932187