I/O 模型

預備知識1: 用戶空間和內核空間

  • 虛擬存儲器
    • 以32位操作系統爲例, 能訪問的內存最大爲4G
      這裏寫圖片描述
  • 0–3G 虛擬地址分配給各個用戶進程(用戶空間)
    • 每個進程都有3G的虛擬地址空間
  • 3–4G 虛擬地址分配給操作系統核心和驅動程序(內核空間)
  • 用戶空間和內核空間不能用指針來傳遞數據()

注意:
- Linux 操作系統和驅動程序運行在內核空間,應用程序運行在用戶空間,兩者不能簡單地使用指針傳遞數據,因爲Linux使用的虛擬內存機制,用戶空間的數據可能被換出,當內核空間使用用戶空間指針時,對應的數據可能不在內存中。用戶空間的內存映射採用段頁式,而內核空間有自己的規則。
- 32位系統用戶進程最大可以訪問3GB,內核代碼可以訪問所有物理內存。
- 64位系統用戶進程最大可以訪問超過512GB,內核代碼可以訪問所有物理內存。
- 用戶態的程序就不能隨意操作內核地址空間裏的數據,具有一定的安全保護作用;於此同時,在實時性方面稍微有所犧牲。也要就是說,只要內核代碼沒有問題,用戶空間程序的錯誤和BUG一般來說不會導致系統崩潰,提高了系統的健壯性

這裏寫圖片描述

內核態與用戶態:
(1)當一個任務(進程)執行系統調用而陷入內核代碼中執行時,稱進程處於內核運行態(內核態)。比如進行文件訪問

(2)當進程在執行用戶自己的代碼時,則稱其處於用戶運行態(用戶態)。

預備知識2: I/O模式

  • 緩存I/O

    • 數據會先被拷貝到操作系統內核的緩衝區中,然後纔會從操作系統內核的緩衝區拷貝到應用程序的地址空間。
  • 進程讀取數據的兩個階段

    • 等待內核數據準備
    • 將數據從內核拷貝到進程中

假設我們有個進程,建立了一個socket , 從服務器讀取數據, 那數據從網絡到達時, 先被讀取到內核的緩衝區, 然後再複製到進程的緩衝區

預備知識3: 進程狀態和阻塞

這裏寫圖片描述

什麼時候會阻塞? 進程正在運行, 需要從硬盤, 網絡等地方讀取數據, 由於IO操作很慢, 進程會被放到阻塞隊列中等待。

IO模型

由於數據的讀取分爲兩個階段,所以IO讀取分爲若干種模式下面的圖是從《Unix網絡編程》書中截取出來的圖片,我認爲這幾張圖很好的解釋了這幾種IO模型的特點。

同步阻塞型IO

這裏寫圖片描述

最常用的I/O模型就是阻塞I/O,缺省的情況下所有文件的操作都是阻塞的。以模型Socket爲例, 進程被阻塞, 直到數據從內核空間複製到用戶空間,在此期間一直會等待。

注意 Socket與數據報(UDP)的區別:前者概念更寬泛,包括後者再加上TCP

同步非阻塞型IO

這裏寫圖片描述

當進程調用recvFrom的時候, 系統不把進程置爲阻塞狀態,相反,而是返回一個標誌符。 這樣進程就可以反覆輪詢內核,詢問數據準備好了沒有, 這樣會耗費大量CPU時間。

異步IO

這裏寫圖片描述

進程告知內核啓動某個操作,並讓內核完成以後通知進程。

IO複用模型

這裏寫圖片描述

進程告訴內容: 我這裏有100多個(假設)socket, 你幫我看看哪一個可以讀了, 然後告訴我, 哪一個socket 好了, 我就會發起receiveFrom調用。本質上IO複用模型也是同步阻塞型IO,但是它與同步阻塞型IO的區別是它可以管理很多socket
應用場景:當需要同時處理多個客戶端接入請求時,可以利用多線程或者I/O多路複用技術進行處理。I/O多路複用技術通過把多個I/O的阻塞複用到同一個select的阻塞上,從而使得系統在單線程的情況下可以同時處理多個客戶端請求。與傳統的多線程/多進程模型相比較,I/O多路複用模型的最大優勢是系統開銷小,系統不需要創建新的額外進程或線程,也不需要維護這些進程和線程的運行。
- 服務器需要同時處理多個監聽狀態或者多個連接狀態的套接字(Socket)

各種IO模型的對比

這裏寫圖片描述

總結

  • 操作系統中的很多概念是關聯的, 例如你理解了虛擬存儲器, 纔有可能理解用戶空間,內核空間, 然後才能真正理解阻塞,非阻塞, 異步,同步
  • 將數據從內核複製到用戶空間都是阻塞的,所謂非阻塞就是等待數據是非阻塞的
  • 程序(進程)阻塞後,CPU不會分配時間片給改程序運行。

問題:

  • 爲什麼異步IO不能完全取代阻塞IO?
    阻塞IO有存在的道理,你想一個業務場景下,必須要某一 步的IO操作完成才能進行後面的任務,後面的所有的操作都建立在這個IO完成上。在這種情況下你就得用阻塞IO 了 。
發佈了29 篇原創文章 · 獲贊 46 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章