UNIX中的五種I/O模型

在Java網絡編程中,應用的較多的主要有BIO,NIO倆種模型,前者爲傳統的阻塞IO模型,後者爲Java1.4後來新加入的非阻塞IO模型,由於後者的性能前者要高出很多,所以開發高性能的應用時,基本都會選擇NIO模型。最典型的比如大名鼎鼎的Netty框架就是基於NIO開發的(Netty框架幾乎無處不在,)。另外還有一種不太常用的Java1.7中新加入的AIO模型,是NIO的2.0版本,應用較少,與NIO的主要區別在於AIO是基於事件回調的。

所有Java的這些IO模型都是基於底層來實現的,我們先來簡單瞭解下操作系統層面上的IO模型,瞭解之後會對Java的實現理解有一定的幫助。在Unix網絡編程一書中定義了5種I/O模型

阻塞式I/O

這是最簡單也是最早出現的I/O模型。來看一下該模型的流程圖

進行IO操作時,進程調用recvfrom,該函數會一直阻塞直到數據到達或者報錯才能返回,從調用recvfrom開始到它返回的整段時間內是被阻塞的。這意味着我們的程序在這段等待的時間內做不了任何事情。

非阻塞I/O

當調用recvfrom沒有數據可返回時,內核立即返回一個EWOULDBLOCK錯誤,直至數據報準備好時,才正常返回。我們可以對它進行輪詢,查看是否有數據到來,但是這麼做的缺點是比較耗費CPU時間。

I/O複用模型

該模型由select與poll函數支持,這兩個函數作用是內核一旦發現進程指定的一個或多個I/O條件就緒時,就會通知進程。

調用select或者poll,使其不阻塞在I/O系統調用上。只阻塞在select或者poll調用,等待數據報套接字變爲可讀。當套接字返回可讀這一條件時,則調用recvfrom把數據讀出。該模型的優勢在於select可以同時等待多個描述符(一個socket的讀寫對應一個描述符)就緒。

信號驅動式I/O

與I/O複用模式區別在於,它可以讓內核在描述符就緒時發送SIGIO信號通知我們。這種模型優勢在於等待數據報到達期間進程不被阻塞。

異步I/O模型

進程會告知內核啓動某個操作,並讓內核在整個操作完成後通知我們,與信號驅動模型區別在於,信號模型通知我們何時可以啓動一個I/O操作,異步模型通知我們I/O操作何時完成。在等待I/O完成期間,我們的進程不被阻塞。

比較

可以看出異步I/O模型的性能是最佳的,幾乎阻塞時間。

參考:UNIX網絡編程

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