筆記-編程-IO模型
筆記-編程-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. 相關概念
- 同步/異步
同步指前後兩件任務,有嚴格的順序一致性;
異步對順序的要求和依賴關系沒那麽強;
- 阻塞/非阻塞
阻塞:請求-響應比較耗時,如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模型