假期小結 BIO, NIO, AIO

雖然忙碌,但仍小有收穫,開心。編程

 

引子

BIO: Blocking IO,阻塞式IO緩存

NIO: Non-blocking IO,非阻塞式IO網絡

AIO: Async IO,異步IO多線程

 

問題

什麼是阻塞式IO/非阻塞式IO,什麼又是同步IO/異步IO呢?框架

 

前提

① IO實際上分爲兩大步:應用程序請求的IO操做、操做系統的IO操做 - 用戶空間和內核空間(kernel)。用戶空間的應用程序須要IO操做,其實是調用的操做系統的IO操做。異步

② kernel的IO操做是須要時間的 - 姑且叫它準備時間吧。函數

 

那問題來了:在這個準備時間裏,操做系統和應用程序都是如何工做的?性能

 

以應用程序讀取數據爲例(這裏不考慮緩存),操做系統其實有兩類回覆:編碼

① 等到須要的數據都準備完畢再回復 -- 中間一直默不做聲,這就是同步IO。操作系統

② 先告訴應用程序數據沒有準備好,而後準備好數據,通知(回調)應用程序或被輪詢 -- 這就是異步IO。

 

那應用程序如何對待這個響應呢?其實仍是兩類:

① 一直等,直接數據都發過來,而後再進行下一步。-- 阻塞IO。

② 先幹別的,而後按期查詢或等待回調。-- 非阻塞IO。

 

小結

阻塞/非阻塞IO 說的是應用程序的IO操做;同步/異步IO 說的是操做系統的IO操做。

注意,異步、非阻塞,都有兩個彼此對應的小分類。

 

略深刻

前面已經說過,操做系統的IO操做分爲同步IO和異步IO。同步IO沒什麼好說的,咱們就來看看異步IO。

異步IO,實際上是三個系統函數select、poll、epoll中的一個(跟Linux內核版本有關),搞C/C++編程的人應該熟悉這個。

雖然select和poll的性能極高,但能處理的數量有限制,沒記錯的話是不能超過1000個,不然性能下降。

epoll的性能略低(固然仍是很高),但能處理的數量很高。

這幾年的Linux核心用的都是epoll,就是說新版本系統上 JDK NIO調用的是epoll。

感興趣的人能夠查閱相關資料瞭解下。

 

注意,這裏說的操做系統都是指Linux。

 

優缺點

查了一些資料,都是用網絡編程爲例來講明BIO、NIO、AIO的區別,這裏就再也不敲代碼了,直接說說彼此的優缺點好了。

BIO:優勢是編碼簡單,容易上手、調試。缺點則是由於多線程自己的問題,①每一個線程都要分配內存空間(最少128K),②線程的切換須要耗費時間。因此,一是線程數量有限;二是線程多了會嚴重下降響應時間。固然也可使用線程池,但又涉及到隊列任務積壓問題。

NIO:恰好跟BIO相反。優勢是速度快,耗費資源少。缺點是編碼複雜,難以上手、調試。

AIO:這個暫時沒研究,不過想一想應該跟js的回調是一個道理。事件驅動(回調),性能高。

 

補充

說到NIO,其實不多有直接使用JDK的NIO的,由於有嚴重bug,會致使Linux下select佔用CPU 100%。雖然說後續有改進,但也只是下降了概率,並無完全消除。

因此建議使用Netty、Mina之類的框架,要好的多。

 

另外,Tomcat,自版本7開始,使用的就是NIO技術,以提高服務性能。

相關文章
相關標籤/搜索