1. 程式人生 > >5種網路IO模型介紹

5種網路IO模型介紹

5種網路IO模型介紹

IO 模型分為以下幾種:

阻塞IO

非阻塞IO

訊號驅動IO

IO多路複用

非同步IO

image0545f4a8ed4d28b9.png

前四個為同步IO

1 阻塞IO
阻塞IO模型圖

一個IO操作需要兩步: 等待資料和拷貝資料。

blocking IO的特點就是在IO執行的兩個階段(等待資料和拷貝資料兩個階段)都被block了。

一直阻塞,知道兩步完成

2 非阻塞IO
image0f982338a87a5a98.png

從圖中可以看出,當用戶程序發出read操作時,如果kernel中的資料還沒有準備好,那麼它並不會block使用者程序,而是立刻返回一個error。從使用者程序角度講 ,它發起一個read操作後,並不需要等待,而是馬上就得到了一個結果。使用者程序判斷結果是一個error時,它就知道資料還沒有準備好,於是它可以再次傳送read操作。一旦kernel中的資料準備好了,並且又再次收到了使用者程序的system call,那麼它馬上就將資料拷貝到了使用者記憶體,然後返回。

等待資料的不用阻塞,而是輪詢check,第二步阻塞。

所以,在非阻塞式IO中,使用者程序其實是需要不斷的主動詢問kernel資料準備好了沒有。

3 多路複用IO
imagefca737bac6fed2ce.png

和第二種一樣,呼叫system call之後,並不等待核心的返回結果而是立即返回。雖然返回結果的呼叫函式是一個非同步的方式,但應用程式會被像select、poll和epoll等具有多個檔案描述符的函式阻塞住,一直等到這個system call有結果返回了,再通知應用程式。這種情況,從IO操作的實際效果來看,多路複用IO和第一種同步阻塞IO是一樣的,應用程式都是一直等到IO操作成功之後(資料已經被寫入或者讀取),才開始進行下面的工作。不同點在於多路複用IO用一個select函式可以為多個檔案描述符提供通知,提供了併發性。舉個例子:例如有一萬個併發的read請求,但是網路上仍然沒有資料,此時這一萬個read會同時各自阻塞,現在用select、poll、epoll這樣的函式來專門負責阻塞同時監聽這一萬個請求的狀態,一旦有資料到達了就負責通知,這樣就將一萬個等待和阻塞轉化為一個專門的函式來負責與管理。

多路複用技術應用於JAVA NIO的核心類庫多路複用器Selector中,目前支援I/O多路複用的系統呼叫有select、pselect、poll、epoll,在linux程式設計中有一段時間一直在使用select做輪詢和網路事件通知的,但是select支援一個程序開啟的socket描述符(FD)收到了限制,一般為1024,由於這一限制,現在使用了epoll代替了select,而epoll支援一個程序開啟的FD不受限制。

和第二個一樣,只是select可以支援併發。

4 非同步IO

image0a91587b8c6f4d1b.png

使用者程序發起read操作之後,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它受到一個asynchronous read之後,首先它會立刻返回,所以不會對使用者程序產生任何block。然後,kernel會等待資料準備完成,然後將資料拷貝到使用者記憶體,當這一切都完成之後,kernel會給使用者程序傳送一個signal,告訴它read操作完成了

實現了真正的非阻塞,從開始發起操作到最後讀取完成,都不需要阻塞。

5 訊號驅動IO

應用程式提交read請求,呼叫system call,然後核心開始處理相應的IO操作,而同時,應用程式並不等核心返回響應,就會開始執行其他的處理操作(應用程式沒有被IO阻塞),當核心執行完畢,返回read響應,就會產生一個訊號或執行一個基於執行緒的回撥函式來完成這次IO處理過程。在這裡IO的讀寫操作是在IO事件發生之後由應用程式來完成。

6 同步和非同步的區別

非同步IO與同步IO的區別在於:同步IO是需要應用程式主動地迴圈去詢問是否有資料,而非同步IO是通過像select等IO多路複用函式來同時檢測多個事件控制代碼來告知應用程式是否有資料。

同步是需要主動等待訊息通知,而非同步則是被動接受訊息通知,通過回撥、通知、狀態等方式來被動獲取訊息。IO多路複用在阻塞到select階段時,使用者程序是主動等待並呼叫select函式來獲取就緒狀態訊息,並且其程序狀態為阻塞。所以IO多路複用是同步阻塞模式。

7 阻塞和非阻塞的區別

呼叫一個方法,一直到拿到結果為止等待,則為阻塞。
呼叫一個方法,直接給你結果,則為非阻塞。

這麼看來,同步和阻塞,非同步和非阻塞看起來意思是一樣的,但是其實不然,同步非同步強調的是方法的結果如何返回,而阻塞非阻塞強調的是執行方法的過程如何執行。比如,你去餐館吃飯,你點了一盤菜,你是繼續等待還是出去等老闆打電話給你說菜好了,這就是同步非同步。而你時不時問老闆說菜好了嗎,老闆可以在你問了之後回答馬上好一直到最後說好了是非阻塞,而阻塞是你問了一次,老闆不說話,直到菜好了端出來回答一句好了。