說明
系列文章:http://www.reibang.com/p/594441fb9c9e
本文完全參考自《Netty權威指南(第2版)》团南,李林峰著钳恕。
Linux 網(wǎng)絡 I/O 模型
Linux內核將所有的外部設備都看做文件來操作,對文件的讀寫會調用內核的系統(tǒng)命令莹规,返回一個file descriptor(fd赔蒲,文件描述符)。而對一個socket的讀寫也會有相應的描述符良漱,稱為socketfd(socket描述符)舞虱,指向內核中的一個結構體。
UNIX提供了5種I/O模型:
- 阻塞I/O模型:在進程中調用recvfrom母市,系統(tǒng)直到數(shù)據(jù)包到達且被復制到應用進程的緩沖區(qū)或發(fā)生錯誤才返回矾兜,在此期間一直會阻塞等待。進程在調用recvfrom開始到它返回的整段時間內都是被阻塞的窒篱,所以被稱為阻塞I/O模型焕刮。
- 非阻塞I/O模型:recvfrom從應用層到內核時,如果該緩沖區(qū)沒有數(shù)據(jù)墙杯,直接返回錯誤配并,一般對非阻塞I/O模型進行輪詢狀態(tài)檢查,看內核是否有數(shù)據(jù)到來高镐。
- I/O復用模型:Linux提供
select/poll
溉旋,進程將一個或多個fd傳遞給select/poll系統(tǒng)調用,阻塞在select操作上嫉髓。select/poll順序掃描fd是否準備就緒观腊,而且支持的fd數(shù)量很有限。epoll是基于事件驅動方式代替循環(huán)掃描算行,性能更高梧油;當有fd就緒時,立即回調函數(shù)rollback州邢。 - 信號驅動I/O模型:系統(tǒng)調用sigaction執(zhí)行信號處理函數(shù)(此系統(tǒng)調用立即返回儡陨,進程繼續(xù)工作,它是非阻塞的)。當數(shù)據(jù)準備就緒時骗村,為該進程生成一個SIGIO信號嫌褪,通過信號回調通知應用程序調用recvfrom來讀取數(shù)據(jù)。
- 異步I/O:告知內核啟動某個操作胚股,并讓內核
在整個操作完成后
通知我們笼痛。與信號驅動模型的主要區(qū)別:信號驅動I/O由內核通知我們何時可以開始一個I/O操作;異步I/O模型由內核通知我們I/O操作何時已經(jīng)完成琅拌。
I/O 多路復用技術
作用
在I/O編程過程中缨伊,當需要同時處理多個客戶端接入請求時,有兩種處理方式:
- 多線程
- I/O多路復用技術
那么I/O多路復用技術有什么好處呢财忽?
把多個I/O的阻塞倘核,復用到同一個select的阻塞上,從而使得系統(tǒng)通過單線程來同時處理多個客戶端請求
即彪,節(jié)省系統(tǒng)資源紧唱。
應用場景
- 服務器需要同時處理多個處于監(jiān)聽狀態(tài)或連接狀態(tài)的套接字;
- 服務器需要同時處理多種網(wǎng)絡協(xié)議的套接字隶校。
支持 I/O 多路復用的模型有哪些漏益?
- select(有缺陷)
- pselect
- poll
- epoll(使用)
epoll 有哪些優(yōu)點?
- 支持一個進程打開的socket描述符不受限制
- I/O效率不會隨著FD數(shù)目的增加而線性下降
- 使用mmap加速內核與用戶空間的消息傳遞
- epoll的API更加簡單
Java 的 I/O 演進
Java的I/O在1.4以前版本并不好深胳,僅有非炒掳蹋基本的功能。
JDK 1.0 ~ JDK 1.3
1.0 ~ 1.3 中的Java I/O類庫相當原始舞终,很多UNIX網(wǎng)絡編程中的概念都沒有體現(xiàn)出來轻庆。
JDK 1.4 NIO
JDK 1.4中,NIO正式隨JDK發(fā)布敛劝,新增了java.nio包余爆,提供了異步I/O開發(fā)的API和類庫
。
JDK 1.7 NIO 2.0
將原來的NIO類庫進行了升級夸盟,成為NIO 2.0蛾方。