五種IO模型介紹和對比

kinnylee發表於2018-12-01

前言

  • unix提供的IO模型有幾種,分別有哪些?
  • 各種IO模型的特點是什麼?他們有什麼區別?
  • 阻塞,非阻塞,同步,非同步的區別?
  • epoll為什麼高效?

概述

普通輸入操作包含的步驟

  • 等待資料準備好
  • 從核心向程式複製資料

網路資料輸入包含的步驟

  • 等待資料從網路送達,到達後被複制到核心緩衝區
  • 把資料從核心緩衝區複製到應用程式緩衝區

IO模型介紹

阻塞式IO

  • 使用系統呼叫,並一直阻塞直到核心將資料準備好,之後再由核心緩衝區複製到使用者態,在等待核心準備的這段時間什麼也幹不了
  • 下圖函式呼叫期間,一直被阻塞,直到資料準備好且從核心複製到使用者程式才返回,這種IO模型為阻塞式IO
  • 阻塞式IO式最流行的IO模型
    五種IO模型介紹和對比

非阻塞式IO

  • 核心在沒有準備好資料的時候會返回錯誤碼,而呼叫程式不會休眠,而是不斷輪詢詢問核心資料是否準備好
  • 下圖函式呼叫時,如果資料沒有準備好,不像阻塞式IO那樣一直被阻塞,而是返回一個錯誤碼。資料準備好時,函式成功返回。
  • 應用程式對這樣一個非阻塞描述符迴圈呼叫成為輪詢。
  • 非阻塞式IO的輪詢會耗費大量cpu,通常在專門提供某一功能的系統中才會使用。通過為套接字的描述符屬性設定非阻塞式,可使用該功能
    五種IO模型介紹和對比

IO多路複用

  • 類似與非阻塞,只不過輪詢不是由使用者執行緒去執行,而是由核心去輪詢,核心監聽程式監聽到資料準備好後,呼叫核心函式複製資料到使用者態
  • 下圖中select這個系統呼叫,充當代理類的角色,不斷輪詢註冊到它這裡的所有需要IO的檔案描述符,有結果時,把結果告訴被代理的recvfrom函式,它本尊再親自出馬去拿資料
  • IO多路複用至少有兩次系統呼叫,如果只有一個代理物件,效能上是不如前面的IO模型的,但是由於它可以同時監聽很多套接字,所以效能比前兩者高
    五種IO模型介紹和對比
  • 多路複用包括:
    • select:線性掃描所有監聽的檔案描述符,不管他們是不是活躍的。有最大數量限制(32位系統1024,64位系統2048)
    • poll:同select,不過資料結構不同,需要分配一個pollfd結構陣列,維護在核心中。它沒有大小限制,不過需要很多複製操作
    • epoll:用於代替poll和select,沒有大小限制。使用一個檔案描述符管理多個檔案描述符,使用紅黑樹儲存。同時用事件驅動代替了輪詢。epoll_ctl中註冊的檔案描述符在事件觸發的時候會通過回撥機制啟用該檔案描述符。epoll_wait便會收到通知。最後,epoll還採用了mmap虛擬記憶體對映技術減少使用者態和核心態資料傳輸的開銷

訊號驅動式IO

  • 使用訊號,核心在資料準備就緒時通過訊號來進行通知
  • 首先開啟訊號驅動io套接字,並使用sigaction系統呼叫來安裝訊號處理程式,核心直接返回,不會阻塞使用者態
  • 資料準備好時,核心會傳送SIGIO訊號,收到訊號後開始進行io操作
    五種IO模型介紹和對比

非同步IO

  • 非同步IO依賴訊號處理程式來進行通知
  • 不過非同步IO與前面IO模型不同的是:前面的都是資料準備階段的阻塞與非阻塞,非同步IO模型通知的是IO操作已經完成,而不是資料準備完成
  • 非同步IO才是真正的非阻塞,主程式只負責做自己的事情,等IO操作完成(資料成功從核心快取區複製到應用程式緩衝區)時通過回撥函式對資料進行處理
  • unix中非同步io函式以aio_或lio_打頭
    五種IO模型介紹和對比

各種IO模型對比

  • 前面四種IO模型的主要區別在第一階段,他們第二階段是一樣的:資料從核心緩衝區複製到呼叫者緩衝區期間都被阻塞住!
  • 前面四種IO都是同步IO:IO操作導致請求程式阻塞,直到IO操作完成
  • 非同步IO:IO操作不導致請求程式阻塞
    五種IO模型介紹和對比

參考

《unix網路程式設計》第一卷

相關文章