你好,我是彤哥,本篇是netty系列的第二篇。linux
歡迎來個人公從號彤哥讀源碼系統地學習源碼&架構的知識。segmentfault
本文將介紹linux中的五種IO模型,同時也會介紹阻塞/非阻塞與同步/異步的區別。架構
對於一次IO操做,數據會先拷貝到內核空間中,而後再從內核空間拷貝到用戶空間中,因此一次read操做,會經歷兩個階段:異步
(1)等待數據準備async
(2)數據從內核空間拷貝到用戶空間ide
基於以上兩個階段就產生了五種不一樣的IO模式。學習
從進程發起IO操做,一直等待上述兩個階段完成。操作系統
兩階段一塊兒阻塞。netty
進程一直詢問IO準備好了沒有,準備好了再發起讀取操做,這時才把數據從內核空間拷貝到用戶空間。code
第一階段不阻塞但要輪詢,第二階段阻塞。
多個鏈接使用同一個select去詢問IO準備好了沒有,若是有準備好了的,就返回有數據準備好了,而後對應的鏈接再發起讀取操做,把數據從內核空間拷貝到用戶空間。
兩階段分開阻塞。
進程發起讀取操做會當即返回,當數據準備好了會以通知的形式告訴進程,進程再發起讀取操做,把數據從內核空間拷貝到用戶空間。
第一階段不阻塞,第二階段阻塞。
進程發起讀取操做會當即返回,等到數據準備好且已經拷貝到用戶空間了再通知進程拿數據。
兩個階段都不阻塞。
各類IO模式同好比下:
同步非同步的區別在於調用操做系統的recvfrom()的時候是否阻塞,可見除了最後的異步IO其它都是同步IO。
select 有最大文件描述符的限制,只能監聽到有幾個文件描述符就緒了,得遍歷全部文件描述符獲取就緒的IO。
poll 沒有最大文件描述符的限制,與select同樣,只能監聽到有幾個文件描述符就緒了,得遍歷全部文件描述符獲取就緒的IO。
epoll 沒有最大文件描述符的限制,它經過回調的機制,一旦某個文件描述符就緒了,迅速激活這個文件描述符,當進程下一次調用epoll_wait()的時候便獲得通知。
因此,在有大量空閒鏈接的時候,epoll的效率要高不少。
Java中的nio使用的是哪一種IO模型呢?
答:Java中的nio其實是new io的縮寫,它使用的是多路複用的IO模型。
本文對IO的五種模型作了很簡短的總結,沒看懂的同窗能夠看看下面這篇文章,講得很詳細。
http://www.javashuo.com/article/p-sqagmtjn-x.html
最後,也歡迎來個人公從號彤哥讀源碼系統地學習源碼&架構的知識。