網路IO模型

2022-07-08 05:54:13 字數 2871 閱讀 5930

io有兩種操作,同步io和非同步io。同步io指的是,必須等待io操作完成後,控制權才返回給使用者程序。非同步io指的是,無須等待io操作完成,就將控制權返回給使用者程序。

網路中的io,由於不同的io裝置有著不同的特點,網路通訊中往往需要等待。常見的有以下4種情況。

(1)輸入操作:等待資料到達套接字接收緩衝區。

(2)輸出操作:等待套接字傳送緩衝區有足夠的空間容納將要傳送的資料。

(3)伺服器接收連線請求:等待新的客戶端連線請求的到來。

(4)客戶端傳送連線請求:等待伺服器會送你個客戶的發起的syn所對應的ack。

當乙個網路io(假設是read)發生時,它會涉及兩個系統物件,乙個是呼叫這個io的程序,另乙個是系統核心。當乙個read操作發生時,它會經歷兩個階段:(1)等待資料準備;(2)將資料從核心拷貝到程序中。

4種網路io模型

(1)阻塞io模型(2)非阻塞io模型(3)多路io復用模型(4)非同步io模型

1.阻塞io模型

在linux中,預設情況下所有的socket都是阻塞的,乙個典型的讀寫流程如下圖:

阻塞和非阻塞的概念描述的是使用者執行緒呼叫核心io操作的方式:阻塞是指io操作需要徹底完成後才返回使用者空間;而非阻塞是指io操作被呼叫後立即返回給使用者乙個狀態值,不需要等到io操作徹底完成。

2.非阻塞io模型

在linux下,可以通過設定socket使io變為非阻塞狀態。當對乙個非阻塞的socket執行read操作時,流程如下圖

3.多路io復用模型

多路io復用,有時也稱為事件驅動io。它的基本原理就是有個函式(如select)會不斷地輪詢所負責的socket,當某個socket有資料到達了,就通知使用者程序,多路io復用模型的流程圖如下:

select、poll和epoll的區別

select、poll和epoll都是多路io復用的機制。多路io復用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。但select、poll和epoll本質上都是同步io,因為它們都需要在讀寫事件就緒後自己負責進行讀寫,即是阻塞的,而非同步io則無須自己負責進行讀寫,非同步i/o的實現會負責把資料從核心拷貝到使用者空間。

下面對這3種多路io復用進行對比。

(1) 首先還是來看常見的select()和poll()。對於網路程式設計來說,一般認為poll比select要高階一些,這主要源於以下幾個原因。

1)poll()不要求開發者在計算最大檔案描述符時進行+1的操作。

2)poll()在應付大數目的檔案描述符的時候速度更快,因為對select()來說核心需要檢查大量描述符對應的fd_set中的每乙個位元位,比較費時。

3)select()可以監控的檔案描述符數目是固定的,相對來說也較少(1024或2048)。如果需要監控數值比較大的檔案描述符,或是分布得很稀疏的較少的描述符,效率也會很低。而對於poll()函式來說,就可以建立特定大小的陣列來儲存監控的描述符,而不受檔案描述符值大小的影響,而且poll()可以監控的檔案數目遠大於select()。

4)對於select()來說,所監控的fd_set在select返回之後會發生變化,所以在下一次進入select()之前都需要重新初始化需要監控的fd_set,poll()函式將監控的輸入和輸出事件分開,允許被監控的檔案陣列被復用而不需要重新初始化。

5)select()函式的超時引數在返回時也是未定義的,考慮到可移植性,每次在超時之後在下一次進入到select()之前都需要重新設定超時引數。

(2)select()的優點如下所述。

1)select的可移植性更好,在某些unix系統上不支援poll().

2)select()對於超時值提供了更好的精度,而poll()是精度較差。

(3)epoll的優點如下所述。

1)支援乙個程序開啟大數目的socket描述符(fd)

select()最不能忍受的是乙個程序所開啟的fd是有一定限制的,由fd_setsize的預設值是1024/2048。對於那些需要支援上萬連線數目的im伺服器來說顯然太少了。這時候可以選擇修改這個巨集然後重新編譯核心。不過epoll則沒有這個限制,它所支援的fd上限是最大可以開啟檔案的數目,這個數字一般大於2048.舉個例子,在1gb記憶體的空間中這個數字一般是10萬左右,具體數目可以使用cat/proc/sys/fs/file-max檢視,一般來說這個數目和系統記憶體關係很大。

2)io效率不隨fd數目增加而線性下降。

傳統的select/poll另乙個致命弱點就是當你擁有乙個很大的socket集合,不過由於網路延遲,任一時間只有部分的socket是「活躍」的,但是selecct/poll每次呼叫都會線性掃瞄全部的集合,導致效率呈現線性下降。但是epoll不存在這個問題,它只會對「活躍」的socket進行操作——這是因為在核心中實現epoll是根據每個fd上面的callback函式實現的。那麼,只有「活躍」的socket才會主動去呼叫callback函式,其他idle狀態socket則不會,在這個點上,epoll實現了乙個「偽」aio,因為這時候推動力由linux核心提供。

3)使用mmap加速核心與使用者空間的訊息傳遞

這點實際上涉及epoll的具體實現。無論是selecct、poll還是epoll都需要核心把fd訊息通知給使用者空間,如何避免不必要的記憶體拷貝就顯得尤為重要。在這點上,epoll是通過核心與使用者空間mmap處於同一塊記憶體實現的。

對於poll來說需要將使用者傳入的pollfd陣列拷貝到核心空間,因為拷貝操作和陣列長度相關,時間上來看,這是乙個o(n)操作,當事情發生後,poll將獲得的資料傳送到使用者空間,並執行釋放記憶體和剝離等待佇列等工作,向使用者空間拷貝資料與剝離等待佇列等操作的時間複雜度同樣是o(n)。

網路IO模型

為了更好地了解io模型,我們需要事先回顧下 同步 非同步 阻塞 非阻塞 1.網路傳輸中的兩個階段 分別是 waitdata 和 copydata send copydata recv waitdata copydata 記住這兩點很重要,因為這些io模型的區別就是在兩個階段上各有不同的情況。2.阻塞...

網路IO模型

一 阻塞io模型 阻塞io基於socket程式 原理 recv接收資料時,不是直接接收資料,而是程式將系統呼叫的命令傳送到作業系統 當作業系統收到接收資料的請求,若此時無資料,作業系統會繼續等待,處於等待資料階段 wait for data階段 這個階段相對漫長 當資料來了,作業系統會拷貝資料 co...

網路I O模型 5種常見的網路I O模型

阻塞與非阻塞 阻塞就是卡在那兒什麼也不做,雙方之間也沒有資訊溝通。非阻塞就是即使對方不能馬上完成請求,雙方之間也有資訊的溝通。同步與非同步 同步就是一件事件只由乙個過程處理完成,不論阻塞與非阻塞,最後完成這個事情的都是同乙個過程 非同步就是一件事由兩個過程完成,前面乙個過程通知,後面乙個過程接受返回...