1. 程式人生 > >筆記-編程-IO模型

筆記-編程-IO模型

阻塞 直接 sync io事件 blocking sock jdk 返回 mage

筆記-編程-IO模型

1. 簡介

常用IO模型

1) 同步阻塞IO(Blocking IO)

2) 同步非阻塞IO(Non-blocking IO)

3) IO多路復用(IO Multiplexing)

4) 異步IO(Asynchronous IO)

5) 信號IO

註:這裏主要討論的是網絡IO,linux和windows下有所不同,不過原理是相似的;

1.1. 相關概念

  1. 同步/異步

同步指前後兩件任務,有嚴格的順序一致性;

異步對順序的要求和依賴關系沒那麽強;

  1. 阻塞/非阻塞

阻塞:請求-響應比較耗時,如IO

非阻塞:請求-響應比較迅速,如沒有等待IP完成就直接返回狀態

2. IO模型

2.1. 阻塞IO

用戶線程在讀寫時被阻塞

數據拷貝指請求到的數據先存放在內核空間, 然後從內核空間拷貝至程序的緩沖區

技術分享圖片

缺點在於如果數據沒有就緒,就會一直阻塞在read方法處。

2.2. 非阻塞IO

用戶線程不斷發起IO請求. 數據未到達時系統返回一狀態值; 數據到達後才真正讀取數據,用戶線程每次請求IO都可以立即返回;

缺點在於需不斷輪詢,無謂地消耗了大量的CPU,一般很少直接使用這種模型,而是在其他IO模型中使用非阻塞IO這一特性

技術分享圖片

2.3. IO多路復用

使用一個線程去輪詢多個socket狀態,只有socket真正有讀寫事件時,才真正調用實際的IO讀寫操作,相比非阻塞,大大減少了資源占用。

一旦事件響應體很大,就會導致後續的事件遲遲得不到處理,並會影響新的事件輪詢。

技術分享圖片

2.4. 異步IO

異步IO才是最理想的IO模型。

技術分享圖片

相比於IO多路復用,異步IO並不常用,因為目前操作系統對異步IO的支持並不完善,IO多路復用也基本夠用. 有很多做法是用IO多路復用模型模擬異步IO(IO事件觸發時不直接通知用戶線程,而是將數據讀寫完畢後放到用戶指定的緩沖區中)。
JDK7已經支持了AIO, netty采用過又放棄了, 據說是性能並沒有多路復用好.

2.5. 信號驅動IO模型

當用戶線程發起一個IO請求操作,會給對應的socket註冊一個信號函數;

然後用戶線程繼續執行,當內核數據就緒時,會發送一個信號給用戶線程,開始IO操作;

一般用於UDP中,對於TCP套接口幾乎沒用的,原因是該信號產生的過於頻繁,並且該信號的出現並沒有告訴我們發生了什麽事情。

技術分享圖片

筆記-編程-IO模型