五種IO模型介紹和對比

前言

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

概述

普通輸入操做包含的步驟

  • 等待數據準備好
  • 從內核向進程複製數據

網絡數據輸入包含的步驟

  • 等待數據從網絡送達,到達後被複制到內核緩衝區
  • 把數據從內核緩衝區複製到應用程序緩衝區

IO模型介紹

阻塞式IO

  • 使用系統調用,並一直阻塞直到內核將數據準備好,以後再由內核緩衝區複製到用戶態,在等待內核準備的這段時間什麼也幹不了
  • 下圖函數調用期間,一直被阻塞,直到數據準備好且從內核複製到用戶程序才返回,這種IO模型爲阻塞式IO
  • 阻塞式IO式最流行的IO模型

非阻塞式IO

  • 內核在沒有準備好數據的時候會返回錯誤碼,而調用程序不會休眠,而是不斷輪詢詢問內核數據是否準備好
  • 下圖函數調用時,若是數據沒有準備好,不像阻塞式IO那樣一直被阻塞,而是返回一個錯誤碼。數據準備好時,函數成功返回。
  • 應用程序對這樣一個非阻塞描述符循環調用成爲輪詢。
  • 非阻塞式IO的輪詢會耗費大量cpu,一般在專門提供某一功能的系統中才會使用。經過爲套接字的描述符屬性設置非阻塞式,可以使用該功能

IO多路複用

  • 相似與非阻塞,只不過輪詢不是由用戶線程去執行,而是由內核去輪詢,內核監聽程序監聽到數據準備好後,調用內核函數複製數據到用戶態
  • 下圖中select這個系統調用,充當代理類的角色,不斷輪詢註冊到它這裏的全部須要IO的文件描述符,有結果時,把結果告訴被代理的recvfrom函數,它本尊再親自出馬去拿數據
  • 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操做完成(數據成功從內核緩存區複製到應用程序緩衝區)時經過回調函數對數據進行處理
  • unix中異步io函數以aio_或lio_打頭

各類IO模型對比

  • 前面四種IO模型的主要區別在第一階段,他們第二階段是同樣的:數據從內核緩衝區複製到調用者緩衝區期間都被阻塞住!
  • 前面四種IO都是同步IO:IO操做致使請求進程阻塞,直到IO操做完成
  • 異步IO:IO操做不致使請求進程阻塞

參考

《unix網絡編程》第一卷編程

相關文章
相關標籤/搜索