最常用的i/o模型,預設情形下,所有檔案操作都是阻塞的。程序空間呼叫recvfrom函式,直到資料報到達且被複製到應用程序的緩衝區中或者發生錯誤時才返回,在此期間,程序會被阻塞一直等待。
recvfrom函式當發現核心緩衝區沒有資料時,直接返回乙個ewouldblock錯誤,一般通過輪詢檢查這個狀態,看核心是否有資料到來。
fd:檔案描述符。乙個檔案的讀寫操作會呼叫核心提供的系統命令,返回乙個fd
socketfd:乙個socket的讀寫的對應的描述符
當需要同時處理多個客戶端接入請求時,可以利用多執行緒或io多路復用技術進行實現。原理是:通過把多個io的阻塞復用到同乙個select的阻塞上,從而使得系統在單執行緒的情況下也可以同時處理多個客戶端請求。
io多路復用最大優勢:系統開銷小。即系統不需要建立新的額外程序或執行緒,也不需要維護這些這些程序和執行緒的執行,降低了系統的維護工作量,節省了系統資源。
io多路復用主要應用場景:①伺服器需要同時處理多個處於監聽或連線狀態的套接字。②伺服器需要同時處理多種網路協議的套接字。
支援io多路復用的系統呼叫有select
、pselect
、poll
、epoll
。在linux網路程式設計中,很長時間使用select,但select的一些固有缺陷導致了它的應用受到了很大的限制,最終linux選擇了epoll。
epoll改進的select缺點如下:
支援乙個程序開啟的socket描述符(fd)不受限制(僅受限於作業系統的最大檔案控制代碼數)。
select最大缺陷是單個程序開啟的fd是有限制的,由fd_setsize
設定,預設是1024。對於那些需要支援上萬個tcp連線的大型伺服器來說太少了。
epoll並沒有這個限制,它所支援的fd上限是作業系統的最大檔案控制代碼數。比如:在1g記憶體大小的機器上大約是10萬個控制代碼左右,具體值可以通過cat /proc/sys/fs/file-max
檢視。
io效率不會隨著fd數目的增加而線性下降。
傳統的select/poll的另乙個弱點:當你擁有乙個很大的socket集合時,由於網路延遲或者鏈路空閒,任一時刻只有少部分的socket時「活躍」 的,但是select/poll每次呼叫都會輪詢全部的集合,導致效率呈現線性下降。
epoll不存在這個問題,它只會對「活躍」的socket進行操作。原因是在核心實現中,epoll是根據每個fd上面的callback函式實現的。只有活躍的socket才會主動呼叫callback函式,其他idle狀態的socket不會。epoll實現了乙個偽aio。
使用mmap加速核心與使用者空間的訊息傳遞。
核心需要把fd訊息通知給使用者空間,如何避免不必要的記憶體複製就顯得非常重要。epoll通過核心和使用者空間mmap同一塊記憶體來避免不必要的記憶體複製。
epoll的api更加簡單。
包括建立乙個epoll描述符、新增監聽事件、阻塞等待所監聽的事件發生、關閉epoll描述符等。
用來克服select/poll缺點的方法不只有epoll,epoll只是一種linux的實現方案。在freebsd(一種類unix作業系統)下有kqueue(實際上是乙個功能相當豐富的kernel事件佇列,不僅僅是select/poll的公升級,還可以處理signal、目錄結構變化、程序等多種事件),而dev/poll 是最古老的solaris的方案,使用難度依次遞增。
首先開啟套接字訊號驅動io功能,並通過系統呼叫sigaction執行乙個訊號處理函式。它是非阻塞的。當資料準備就緒後,會為該程序生成乙個sigio訊號,通過訊號**通知應用程式呼叫recvfrom來讀取資料,並通知主迴圈函式處理資料。
告知核心啟動某個操作,並讓核心在整個操作完成後(包括將資料從核心複製到使用者自己的緩衝區)通知我們。同樣是非阻塞的。
這種模型與訊號驅動模型的主要區別是:訊號驅動io由核心通知我們何時可以開始乙個io操作;非同步io模型由核心通知我們io操作何時已經完成。
網路IO模型
為了更好地了解io模型,我們需要事先回顧下 同步 非同步 阻塞 非阻塞 1.網路傳輸中的兩個階段 分別是 waitdata 和 copydata send copydata recv waitdata copydata 記住這兩點很重要,因為這些io模型的區別就是在兩個階段上各有不同的情況。2.阻塞...
網路IO模型
io有兩種操作,同步io和非同步io。同步io指的是,必須等待io操作完成後,控制權才返回給使用者程序。非同步io指的是,無須等待io操作完成,就將控制權返回給使用者程序。網路中的io,由於不同的io裝置有著不同的特點,網路通訊中往往需要等待。常見的有以下4種情況。1 輸入操作 等待資料到達套接字接...
網路IO模型
一 阻塞io模型 阻塞io基於socket程式 原理 recv接收資料時,不是直接接收資料,而是程式將系統呼叫的命令傳送到作業系統 當作業系統收到接收資料的請求,若此時無資料,作業系統會繼續等待,處於等待資料階段 wait for data階段 這個階段相對漫長 當資料來了,作業系統會拷貝資料 co...