淺聊Linux的五種IO模型

微信搜索:碼農StayUp
主頁地址: https://gozhuyinglong.github.io
源碼分享: https://github.com/gozhuyinglong/blog-demos

在平常 Coding 中,多多少少都會接觸到網絡 IO,就會想要深刻了解一下。看了不少文章,老是雲裏霧裏的感受,直到讀了《UNIX網絡編程 卷1:套接字聯網API》中的介紹後,才豁然開朗。這裏就給你們分享一下,若有不對,歡迎指出。git

1. 概念說明

爲了便於理解後面的內容,咱們先來了解一些概念。github

1.1 Socket

Socket 中文翻譯爲套接字,是計算機網絡中進程間進行雙向通訊的端點的抽象。一個 Socket 表明了網絡通訊的一端,是由操做系統提供的進程間通訊機制。編程

  • 在操做系統中,一般會爲應用程序提供一組應用程序接口,稱爲 Socket 接口(Socket API)。應用程序能夠經過 Socket 接口,來使用網絡 Socket,以進行數據的傳輸。
  • 一個 Socket 由IP地址和端口組成,即:Socket 地址 = IP地址 : 端口號。
  • 在同一臺計算機上,TCP 協議與 UDP 協議能夠同時使用相同的端口(Port),而互不干擾。
  • 要想實現網絡通訊,至少須要一對 Socket,其中一個運行在客戶端,稱之爲 Client Socket;另外一個運行在服務器端,稱之爲 Server Socket。
  • Socket 之間的鏈接過程能夠分爲三個步驟:(1)服務器監聽;(2)客戶端鏈接;(3)鏈接確認。

Socket

1.2 Socket 緩衝區

每一個 Socket 被建立後,都會在內核中分配兩個緩衝區:輸入緩衝區和輸出緩衝區。服務器

  • 經過 Socket 發送數據並不會當即向網絡中傳輸數據,而是先將數據寫入到輸出緩衝區中,再由 TCP 協議將數據從輸出緩衝區發送到目標主機。
  • 經過 Socket 接收數據也是如此,也是從輸入緩衝區中讀取數據,而不是直接從網絡中讀取。

Socket緩衝區

1.3 用戶空間、內核空間、系統調用

操做系統的進程空間能夠分爲用戶空間(User Space)和內核空間(Kernel Space),它們須要不一樣的執行權限。微信

  • 大多數系統交互式操做須要在內核空間中運行,好比設備 IO 操做。
  • 咱們的應用程序運行在用戶空間,是不具有系統級的直接操做權限的。若是應用程序想要訪問系統核心功能,必須經過系統調用(System Call)來完成。好比調用recv()函數,會將輸入緩衝區中的內容拷貝到用戶緩衝區。
  • 系統調用運行在內核空間,是操做系統爲應用程序提供的接口。

用戶空間、內核空間、系統調用

下面列舉了一些 Linux 操做系統中的系統調用接口(部分函數後面章節會用到):網絡

  • socketcall socket系統調用
  • socket 創建socket
  • bind 綁定socket到端口
  • connect 鏈接遠程主機
  • accept 響應socket鏈接請求
  • send 經過socket發送信息
  • sendto 發送UDP信息
  • recv 經過socket接收信息
  • recvfrom 接收UDP信息
  • listen 監聽socket端口
  • select 對多路同步IO進行輪詢
  • shutdown 關閉socket上的鏈接
  • sigaction 設置對指定信號的處理方法

1.4 阻塞與非阻塞

阻塞與非阻塞,用於描述調用者在等待返回結果時的狀態。異步

  • 阻塞:調用者發起請求後,會一直等待返回結果,這期間當前線程會被掛起(阻塞)。
  • 非阻塞:調用者發起請求後,會馬上返回,當前線程也不會阻塞。該調用不會馬上獲得結果,調用者須要定時輪詢查看處理狀態。

1.5 同步與異步

而同步與異步,用於描述調用結果的返回機制(或者叫通訊機制)。socket

  • 同步:調用者發起請求後,會一直等待返回結果,即由調用者主動等待這個調用結果。
  • 異步:調用者發起請求後,會馬上返回,但不會馬上獲得這個結果,而是由被調者在執行結束後主動通知(如 Callback)調用者。

2. 五種 IO 模型

IO 模型是指:用什麼樣的通道或者說是通訊模式進行數據的傳輸,這很大程序上決定了程序通訊的性能。函數

Linux 系統爲咱們提供五種可用的 IO 模型:阻塞式 IO 模型、非阻塞式 IO 模型、IO 多路複用模型、信號驅動 IO 模型和異步 IO 模型。性能

2.1 阻塞式 IO 模型

阻塞式 IO (Blocking IO):應用進程從發起 IO 系統調用,至內核返回成功標識,這整個期間是處於阻塞狀態的。

阻塞式 IO 模型

2.2 非阻塞式 IO 模型

非阻塞式IO(Non-Blocking IO):應用進程能夠將 Socket 設置爲非阻塞,這樣應用進程在發起 IO 系統調用後,會馬上返回。應用進程能夠輪詢的發起 IO 系統調用,直到內核返回成功標識。

非阻塞式 IO 模型

2.3 IO 多路複用模型

IO 多路複用(IO Multiplexin):能夠將多個應用進程的 Socket 註冊到一個 Select(多路複用器)上,而後使用一個進程來監聽該 Select(該操做會阻塞),Select 會監聽全部註冊進來的 Socket。只要有一個 Socket 的數據準備好,就會返回該Socket。再由應用進程發起 IO 系統調用,來完成數據讀取。

IO 多路複用模型

2.4 信號驅動 IO 模型

信號驅動 IO(Signal Driven IO):能夠爲 Socket 開啓信號驅動 IO 功能,應用進程需向內核註冊一個信號處理程序,該操做並當即返回。當內核中有數據準備好,會發送一個信號給應用進程,應用進程即可以在信號處理程序中發起 IO 系統調用,來完成數據讀取了。

信號驅動 IO 模型

2.5 異步 IO 模型

異步 IO(Asynchronous IO): 應用進程發起 IO 系統調用後,會當即返回。當內核中數據徹底準備後,而且也複製到了用戶空間,會產生一個信號來通知應用進程。

異步 IO 模型

3. 總結

從上述五種 IO 模型能夠看出,應用進程對內核發起 IO 系統調用後,內核會通過兩個階段來完成數據的傳輸:

  • 第一階段:等待數據。即應用進程發起 IO 系統調用後,會一直等待數據;當有數據傳入服務器,會將數據放入內核空間,此時數據準備好。
  • 第二階段:將數據從內核空間複製到用戶空間,並返回給應用程序成功標識。

五種 IO 模型對比

前四種模型的第二階段是相同的,都是處於阻塞狀態,其主要區別在第一階段。而異步 IO 模型則不一樣,應用進程在這兩個階段是徹底不阻塞的。

IO 模型 第一階段 第二階段
阻塞式IO 阻塞 阻塞
非阻塞式IO 非阻塞 阻塞
IO多路程複用 阻塞(Select) 阻塞
信號驅動式IO 異步 阻塞
異步IO 異步 異步

參考資料

推薦閱讀

相關文章
相關標籤/搜索