網絡IO總結

網絡IO的模式包括同步IO,異步IO,阻塞IO,非阻塞IO;這些IO模式之間的區別和聯繫是任何一個搞網絡編程(Socket編程)的人必須弄清楚的問題,下面我們就來一層層的揭開他們的面紗吧。在Unix網絡編程第一卷第六章中討論了五種IO模型:

1. 阻塞IO(Blocking IO)

2. 非阻塞IO(Nonblocking IO)

3. IO多路複用(IO multiplexing)

4. Signal Driven IO(實際中一般不使用)

5. 異步IO(Asynchronous IO)

由於第4種在實際中一般不使用,所以接下來在本文中我們就討論其餘4種模型;在討論模型之前,我們首先要明確IO過程中兩個非常重要的步驟(所有的IO模型都是用戶進程和內核在這兩個步驟上交互模式不同):

1. 內核等待數據準備(內核等待協議棧中運輸層接收緩衝區或發送緩衝區就緒)

2. 內核將緩衝區中的數據拷貝用戶態進程的地址空間中

Blocking IO

在Linux中,默認的Socket通信模式就是阻塞IO,該模式的過程如下圖所示:

從上圖可以看出,當用戶進程開始調用recvfrom的時候,內核就開始等待數據,當數據準備好之後,內核立即將數據從內核緩存中拷貝到進程的地址空間中,整個過程完成之後,recvfrom調用返回;在此之間,用戶進程被阻塞。

Nonblocking IO

當用戶希望以非阻塞的方式進行IO通信時,可以設置Socket爲非阻塞,非阻塞的模式圖如下:

當用戶進程調用recvfrom時,假如此時內核正在等待數據,則該調用會立即返回錯誤;假如此時數據已經準備好了,則內核會立即將數據拷貝到用戶進程的地址空間中併成功返回;上面圖示的是應用進程在不斷的輪詢,直到內核中數據準備好併成功返回爲止。

IO multiplexing

IO多路複用也被稱爲事件驅動IO(Event Driven IO),我們常用的select, poll, epoll等系統調用就是這種模型;這種模型的優點是可以同時處理多個socket連接。其基本原理是select/epoll系統調用會不斷輪詢所負責的所有socket連接,一旦某個socket的數據已經準備好,select便立即返回;然後用戶進程調用recvfrom觸發內核將該socket對應的數據從內核空間拷貝到應用進程的地址空間中併成功返回。

在IO multiplexing Model中,socket一般都被設置成non-blocking,但是,如上圖所示,內核在等待數據就緒的時候,用戶進程其實是block的,只不過進程是被select這個函數block,而不是被socket IO給block。

該模型用於服務器中對多個網絡併發連接進行處理會非常有效,分佈式緩存Memcached的服務端及常用的Web服務器就採用這種模型,Libevent就是基於這個模型實現的庫。

異步IO

Linux中異步IO其實用的非常少,它的模型如下圖所示:

從圖中我們可以看出,當用戶進程發起IO請求時,如果內核數據沒有準備好,則會立刻返回;返回後用戶進程繼續做之後的事情,而內核則等待數據就緒並將數據從內核拷貝到用戶空間,同時發送aio_read中指定的信號給用戶進程,告訴它數據已經成功發送給它。

下面我們來看看阻塞和非阻塞、同步和異步的內涵及區別:

阻塞、非阻塞是指當調用一個函數時,他是否能夠立即返回;

同步、異步是指進程間通信是否經過協調,是進程間通信的模型;比如進程A需要等待進程B執行完某件事情之後才能繼續執行,這就是同步;假如進程A的執行和進程B的執行好不相干,這就是異步;

因此,我們可以說阻塞調用或非阻塞調用,但不能說同步調用及異步調用,只能說同步通信或異步通信

發佈了65 篇原創文章 · 獲贊 6 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章