對IO的一點理解

在Linux操作系統層面,網絡操作即爲IO操作,總共有:阻塞式,非阻塞式,複用模型,信號驅動和異步五種IO模型。阻塞式IO操作請求發起以後,從網卡等待/讀取數據,內核/到用戶態的拷貝,整個IO過程中,用戶的線程都是處於阻塞狀態。非阻塞與阻塞的區別在於應用層不會等待網卡接收數據,即在內核數據未準備好之前,IO將返回EWOULDBLOCK,用戶端通過主動輪詢,直到內核態數據準備好,然後再主動發起內核態數據到用戶態的拷貝讀操作(阻塞)。在非阻塞IO中,每個IO的應用層代碼都需要主動地去內核態輪詢直到數據OK,在IO複用模型中,將“輪詢/事件驅動”的工作交給一個單獨的select/epoll的IO句柄去做,即所謂的IO複用。信號驅動IO是向內核註冊信號回調函數,在數據OK的時候自動觸發回調函數,進而可以在回調函數中啓用數據的讀取,即由內核告訴我們何時可以開始IO操作。異步IO是將IO數據讀取到用戶態內存的函數註冊到系統中,在內核數據OK的時候,自動完成內核態到用戶態的拷貝,並通知應用態數據已經讀取完成,即由內核告訴我們何時IO操作已經完成。
JAVAIO也經歷來上面幾次演化,從最早的BIO(阻塞式/非阻塞IO),到1.4版本的NIO(IO複用),到1.7版本的NIO2.0/AIO(異步IO);基於早期BIO來實現高併發網絡服務器都是依賴多線程來實現,但是線程開銷較大,BIO的瓶頸明顯,NIO的出現解決了這一大難題,基於IO複用解決了IO高併發;但是NIO有也有幾個缺點:API可用性較低(拿ByteBuffer來說,共用一個curent指針,讀寫切換需要進行flip和rewind,相當麻煩);僅僅是API,如果想在NIO上實現一個網絡模型,還需要自己寫很多比如線程池,解碼,半包/粘包,限流等邏輯;最後就是著名的NIO-Epoll死循環的BUG因爲這幾個原因,促使了很多JAVA-IO通信框架的出現,Netty就是其中一員,它也因爲高度的穩定性,功能性,性能等特性,成爲Javaer們的首選。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章