IO模型對比:同步、異步、阻塞、非阻塞

最近工做接觸到了網絡服務同步和異步,因此學習了下《UNIX網絡編程》,在此做下總結。編程

1、I/O模型

輸入/輸出(I/O)是在主存和外部設備(如磁盤驅動器、終端和網絡)之間拷貝數據的過程。輸入是從I/O設備拷貝數據到主存,而輸出是從主存拷貝數據到I/O設備。好比,網絡可視爲一個I/O設備,做爲數據源和數據接收方。系統能夠通過網絡讀取其餘機器發送來的數據,並將數據複製到本身主存中。 網絡

下面分別介紹Unix的5種I/O模型:多線程

  • 阻塞式IO
  • 非阻塞IO
  • IO複用
  • 信號驅動IO
  • 異步IO

一個輸入操做一般爲如下兩個階段:異步

(1)等待數據準備好;socket

(2)從內核複製數據到進程;函數

拿網絡中客戶端請求服務的例子說明五種模型。學習

在網絡請求中,套接字(socket)是實現通訊的一個端點,應用程序能夠經過它發送或接收數據,可對其進行像對文件同樣的打開、讀寫和關閉等操做。線程

對於一個soket上的輸入操做:3d

(1)等待數據從網絡中到達。數據到達時被複制到內核中的緩衝區;指針

(2)把數據從內核緩衝區複製到應用進程緩衝區。

1. 阻塞式IO模型

阻塞式IO模型是最經常使用的,咱們將recvfrom做爲系統調用,來觀察應用進程和內核之間的區別。下圖中進程調用recvfrom,該系統調用直到數據報準備好且拷貝到應用緩衝區或者出錯才返回,也就是說在數據返回以前,進程被阻塞,當進程返回成功指示後,才能夠開始下面的處理。

 

2. 非阻塞式IO模型

下圖中,前三次調用recvfrom,數據還沒準備好,內核會當即返回一個EWOULDBLOCK錯誤,直到第四次調用時,數據準備好被拷貝到應用緩衝區,該系統調用返回成功指示,接下來開始處理數據。當應用進程像這樣對一個非阻塞描述字循環調用recvfrom時,這實際上就是輪詢(polling)。

應用程序不斷地查詢內核,檢查數據是否準備好,這對CPU來講是一種浪費,因此這種模型比較少見。

 

 

 

3. IO複用模型

IO複用是指經過調用select,poll或者epoll函數,監聽多個socket鏈接,每新來一個socket鏈接,就會被加入到監聽列表,實現單個線程同時處理多個網絡鏈接的IO。基本原理是經過select,poll或epoll不斷輪詢負責的所有socket,當其中一個數據準備好,就通知進程。而後調用recvfrom拷貝數據從內核到進程,返回成功指示後,進行下一步處理。

應用進程雖然不會被socket的IO阻塞,但一直被select,poll或epoll阻塞。若是socket數不是不少的話,使用IO複用模型可能比多線程 + 阻塞IO延遲更大,由於IO複用模型相對比以前的模型須要兩次系統調用,它的優點在於能處理較多的鏈接。

 

 

 

4. 信號驅動IO模型

該模型經過系統調用sigaction安裝一個信號處理程序。當內核準備好數據後,發送信號告知進程。在信號處理程序中調用recvfrom讀取數據,並通知主循環。這種模型的好處是當等待數據報到達時,IO不被阻塞。主循環能夠繼續執行,只是等待信號處理程序的通知:數據已準備好被讀。

 

 

5. 異步IO模型

異步IO模型讓內核完成整個操做(包括將數據從內核拷貝到進程緩衝區)後才進行通知應用進程。這個模型和信號驅動模型的主要區別在於:信號驅動IO是由內核通知咱們什麼時候能夠啓動一個IO操做,而異步IO是由內核通知咱們IO操做什麼時候完成。

下圖中調用aio_read,傳遞內核描述字、緩衝區指針、緩衝區大小、文件偏移,並告訴內核整個操做完成時如何通知咱們。該系統調用當即返回,不阻塞於IO操做。該圖中,內核在操做完成後傳遞一個信號,該信號直到數據被拷貝到緩衝區才產生,這是和信號驅動IO的不一樣之處。

 

 

2、IO模型區別

1. 對比

從這兩個階段來看,前四種模型在第一階段有所不一樣,但第二個階段基本相同,把數據從內核拷貝到應用進程的緩衝區時,進程被阻塞於recvfrom調用。異步IO模型的兩個階段都不一樣於前四種模型。

 

 

2. 同步vs異步

同步IO操做會阻塞請求進程,直到IO操做完成。

異步IO操做不會阻塞請求進程。

前四種模型:阻塞IO模型、非阻塞IO模型、IO複用模型和信號驅動IO都是同步IO模型,由於真正的IO操做(recvfrom)阻塞進程。

相關文章
相關標籤/搜索