Linux下的五種I/O模型

一、關于I/O模型的引出

我們都知道,為了OS的安全性等的考慮,進程是無法直接操作I/O設備的,其必須通過系統調用請求內核來協助完成I/O動作,而內核會為每個I/O設備維護一個buffer。如下圖所示:
  


  整個請求過程為:用戶進程發起請求,內核接受到請求后,從I/O設備中獲取數據到buffer中,再將buffer中的數據copy到用戶進程的地址空間,該用戶進程獲取到數據后再響應客戶端。
  在整個請求過程中,數據輸入至buffer需要時間,而從buffer復制數據至進程也需要時間。因此根據在這兩段時間內等待方式的不同,I/O動作可以分為以下五種模式:
  (1) 阻塞I/O (Blocking I/O)
  (2) 非阻塞I/O (Non-Blocking I/O)
  (3) I/O復用(I/O Multiplexing)
  (4) 信號驅動的I/O (Signal Driven I/O)
  (5) 異步I/O (Asynchrnous I/O)

二、關于I/O模型的劃分
  阻塞:調用的進程一直處于等待狀態,直到操作完成。
  非阻塞:在內核的數據還未準備好時,會立即返回,進程可以去干其他事情。
  從同步異步,以及阻塞、非阻塞兩個維度來劃分來看:
    

三、I/O模型分述
  1、阻塞I/O
    


  從上圖可以看到在整個過程中,當用戶進程進行系統調用時,內核就開始了I/O的第一個階段,準備數據到緩沖區中,當數據都準備完成后,則將數據從內核緩沖區中拷貝到用戶進程的內存中,這時用戶進程才解除block的狀態重新運行。
  所以,Blocking I/O的特點就是在I/O執行的兩個階段都被block了。

  2、非阻塞I/O
    


  從上圖可以看到在I/O執行的兩個階段中,用戶進程只有在第二個階段被阻塞了,而第一個階段沒有阻塞,但是在第一個階段中,用戶進程需要盲等,不停的去輪詢內核,看數據是否準備好了,因此該模型是比較消耗CPU的。

3、I/O復用
    


  從上圖可以看到在I/O復用模型中,I/O執行的兩個階段都是用戶進程都是阻塞的,但是兩個階段是獨立的,在一次完整的I/O操作中,該用戶進程是發起了兩次系統調用。

 4、信號驅動的I/O
    


  該模型也叫作基于事件驅動的I/O模型,可以看到該模型中,只有在I/O執行的第二階段阻塞了用戶進程,而在第一階段是沒有阻塞的。
  乍看起來感覺和非阻塞模型很相似,其實不同之處就在于,該模型在I/O執行的第一階段,當數據準備完成之后,會主動的通知用戶進程數據已經準備完成,即對用戶進程做一個回調。該通知分為兩種,一為水平觸發,即如果用戶進程不響應則會一直發送通知,二為邊緣觸發,即只通知一次。

5、異步I/O
    


  在該模型中,當用戶進程發起系統調用后,立刻就可以開始去做其它的事情,然后直到I/O執行的兩個階段都完成之后,內核會給用戶進程發送通知,告訴用戶進程操作已經完成了。

四、五種模型總結
  

參考
  1. 子夜,http://www.cnblogs.com/chy2055/p/5220793.html
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容