前四種都是同步,只有最後一種纔是異步IO。html
簡介:進程會一直阻塞,直到數據拷貝完成
應用程序調用一個IO函數,致使應用程序阻塞,等待數據準備好。 若是數據沒有準備好,一直等待….數據準備好了,從內核拷貝到用戶空間,IO函數返回成功指示。linux
可能阻塞套接字的Windows Sockets API調用分爲如下四種: windows
1.輸入操做: recv()、recvfrom()、WSARecv()和WSARecvfrom()函數。以阻塞套接字爲參數調用該函數接收數據。若是此時套接字緩衝區內沒有數據可讀,則調用線程在數據到來前一直睡眠。 服務器
2.輸出操做: send()、sendto()、WSASend()和WSASendto()函數。以阻塞套接字爲參數調用該函數發送數據。若是套接字緩衝區沒有可用空間,線程會一直睡眠,直到有空間。 網絡
3.接受鏈接:accept()和WSAAcept()函數。以阻塞套接字爲參數調用該函數,等待接受對方的鏈接請求。若是此時沒有鏈接請求,線程就會進入睡眠狀態。 app
4.外出鏈接:connect()和WSAConnect()函數。對於TCP鏈接,客戶端以阻塞套接字爲參數,調用該函數向服務器發起鏈接。該函數在收到服務器的應答前,不會返回。這意味着TCP鏈接總會等待至少到服務器的一次往返時間。異步
簡介:非阻塞IO經過進程反覆調用IO函數(屢次系統調用,並立刻返回);在數據拷貝的過程當中,進程是阻塞的;socket
咱們把一個SOCKET接口設置爲非阻塞就是告訴內核,當所請求的I/O操做沒法完成時,不要將進程睡眠,而是返回一個錯誤。這樣咱們的I/O操做函數將不斷的測試數據是否已經準備好,若是沒有準備好,繼續測試,直到數據準備好爲止。在這個不斷測試的過程當中,會大量的佔用CPU的時間。async
非阻塞套接字在控制創建的多個鏈接,在數據的收發量不均,時間不定時,明顯具備優點。這種套接字在使用上存在必定難度,但只要排除了這些困難,它在功能上仍是很是強大的。函數
簡介:主要是select和epoll;對一個IO端口,兩次調用,兩次返回,比阻塞IO並無什麼優越性;關鍵是能實現同時對多個IO端口進行監聽;
I/O複用模型會用到select、poll、epoll函數,這幾個函數也會使進程阻塞,可是和阻塞I/O所不一樣的的,這兩個函數能夠同時阻塞多個I/O操做。並且能夠同時對多個讀操做,多個寫操做的I/O函數進行檢測,直到有數據可讀或可寫時,才真正調用I/O操做函數。
簡介:兩次調用,兩次返回;
首先咱們容許套接口進行信號驅動I/O,並安裝一個信號處理函數,進程繼續運行並不阻塞。當數據準備好時,進程會收到一個SIGIO信號,能夠在信號處理函數中調用I/O操做函數處理數據。
簡介:數據拷貝的時候進程無需阻塞。
當一個異步過程調用發出後,調用者不能馬上獲得結果。實際處理這個調用的部件在完成後,經過狀態、通知和回調來通知調用者的輸入輸出操做
網上有個比喻很好的說明這些模型,在這裏引用一下。
老陳有一個在外地工做的女兒,不能常常回來,老陳和她經過信件聯繫。他們的信會被郵遞員投遞到他們的信箱裏。
老陳很是想看到女兒的信。以致於他每隔10分鐘就下樓檢查信箱,看是否有女兒的信~~~~~
在這種狀況下,「下樓檢查信箱」而後回到樓上耽誤了老陳太多的時間,以致於老陳沒法作其餘工做。
後來,老陳使用了微軟公司的新式信箱。這種信箱很是先進,一旦信箱裏有新的信件,蓋茨就會給老陳打電話:喂,大爺,你有新的信件了!今後,老陳不再必頻繁上下樓檢查信箱了,牙也不疼了,你瞅準了,藍天……不是,微軟~~~~~~~~
後來,微軟的信箱很是暢銷,購買微軟信箱的人以百萬計數……以致於蓋茨天天24小時給客戶打電話,累得腰痠背痛,喝蟻力神都很差使~~~~~~
微軟改進了他們的信箱:在客戶的家中添加一個附加裝置,這個裝置會監視客戶的信箱,每當新的信件來臨,此裝置會發出「新信件到達」聲,提醒老陳去收信。蓋茨終於能夠睡覺了。
後來,微軟經過調查發現,老陳不喜歡上下樓收發信件,由於上下樓其實很浪費時間。因而微軟再次改進他們的信箱。新式的信箱採用了更爲先進的技術,只要用戶告訴微軟本身的家在幾樓幾號,新式信箱會把信件直接傳送到用戶的家中,而後告訴用戶,你的信件已經放到你的家中了!老陳很高興,由於他沒必要再親自收發信件了!
老陳接收到新的信件後,通常的程序是:打開信封—-掏出信紙—-閱讀信件—-回覆信件……爲了進一步減輕用戶負擔,微軟又開發了一種新的技術:用戶只要告訴微軟對信件的操做步驟,微軟信箱將按照這些步驟去處理信件,再也不須要用戶親自拆信/閱讀/回覆了!老陳終於過上了小資生活!
微軟信箱彷佛很完美,老陳也很滿意。可是在一些大公司狀況卻徹底不一樣!這些大公司有數以萬計的信箱,每秒鐘都有數以百計的信件須要處理,以致於微軟信箱常常因超負荷運轉而崩潰!須要從新啓動!微軟不得不使出殺手鐗……
微軟給每一個大公司派了一名名叫「Completion Port」的超級機器人,讓這個機器人去處理那些信件!
其實,上面每種模型都有優勢,要根據程序需求而適當選擇合適的模型,前面三種模型效率已經比較高,實現起來難道不大,不少通常的網絡程序都採用前三種模型,只有對網絡要求特別高的一些服務器纔會考慮用後面的那些模型。MFC中的CAsyncSocket類就是用的WSAAsyncSelect模型,電驢中也是用的這種,不過在尋找對應socket的時候進行了優化,查找更快,在GridCast中採用的是WSAEventSelect模型,等待。
OIO 就是同步I/O,
在JDK 1.4版本以後纔開始支持異步IO,其實NIO也是使用操做系統的IO模型,但在各操做系統上的實現方式也不太同樣
在Windows系統使用的是Select模型,而不是性能更高的IOCP,緣由就是並不是全部Windows都支持IOCP,IOCP在windows NT 3.5中被引入,只支持WindowsNT和windows 2000。(參考:http://www.cnblogs.com/jobs/archive/2006/11/22/568023.html)
在Linux系統上使用的是多路複用IO,JDK 6以前用的是poll模型,JDK 7中使用epoll。(參考:http://www.cnblogs.com/jobs/archive/2006/11/22/568022.html)
JDK 7中出現了AIO,其實AIO就是NIO的加強版,由於JDK 6以前用的是poll,JDK 7用的是epoll,而epoll就是poll的加強版。
http://blog.csdn.net/hguisu/article/details/7453390
Java NIO和操做系統I/O模型
http://wugc.iteye.com/blog/986997
IO - 同步,異步,阻塞,非阻塞 (亡羊補牢篇)
http://blog.csdn.net/historyasamirror/article/details/5778378
Java NIO原理 圖文分析及代碼實現
http://weixiaolu.iteye.com/blog/1479656
Java IO模型
http://blog.csdn.net/shanpengfei77/article/details/8161077
Windows I/O模型、同步/異步、阻塞/非阻塞
http://www.linuxnote.org/windows-i-o-model-synchronous-asynchronous-blocking-non-blocking.html