一講到網絡編程的I/O模型,總會涉及到這幾個概念。問了不少人,沒幾個能清晰地講出他們之間的區別聯繫,甚至在網絡上也有不少不一樣的觀點,也不知是中國文字釋義的博大精深,仍是原本這幾個概念就是繞人不倦。今天我也來給你們講解一下我對這幾個概念的理解。編程
既然網絡上衆說紛紜,不如找個權威參考一下,這個權威就是《UNIX網絡編程:卷一》第六章——I/O複用。書中向咱們說起了5種類UNIX下可用的I/O模型:網絡
阻塞式I/O;異步
非阻塞式I/O;ide
I/O複用(select,poll,epoll...);函數
信號驅動式I/O(SIGIO);spa
異步I/O(POSIX的aio_系列函數);操作系統
阻塞式I/O模型:默認狀況下,全部套接字都是阻塞的。怎麼理解?先理解這麼個流程,一個輸入操做一般包括兩個不一樣階段:線程
(1)等待數據準備好;
(2)從內核向進程複製數據。code
對於一個套接字上的輸入操做,第一步一般涉及等待數據從網絡中到達。當全部等待分組到達時,它被複制到內核中的某個緩衝區。第二步就是把數據從內核緩衝區複製到應用程序緩衝區。 好,下面咱們以阻塞套接字的recvfrom的的調用圖來講明阻塞orm
標紅的這部分過程就是阻塞,直到阻塞結束recvfrom才能返回。
非阻塞式I/O: 如下這句話很重要:進程把一個套接字設置成非阻塞是在通知內核,當所請求的I/O操做非得把本進程投入睡眠才能完成時,不要把進程投入睡眠,而是返回一個錯誤。看看非阻塞的套接字的recvfrom操做如何進行
能夠看出recvfrom老是當即返回。
I/O多路複用:雖然I/O多路複用的函數也是阻塞的,可是其與以上兩種仍是有不一樣的,I/O多路複用是阻塞在select,epoll這樣的系統調用之上,而沒有阻塞在真正的I/O系統調用如recvfrom之上。如圖
信號驅動式I/O:用的不多,就不作講解了。直接上圖
異步I/O:這類函數的工做機制是告知內核啓動某個操做,並讓內核在整個操做(包括將數據從內核拷貝到用戶空間)完成後通知咱們。如圖:
注意紅線標記處說明在調用時就能夠立馬返回,等函數操做完成會通知咱們。
等等,你們必定要問了,同步這個概念你怎麼沒涉及啊?別急,您先看總結。 其實前四種I/O模型都是同步I/O操做,他們的區別在於第一階段,而他們的第二階段是同樣的:在數據從內核複製到應用緩衝區期間(用戶空間),進程阻塞於recvfrom調用。相反,異步I/O模型在這兩個階段都要處理。
再看POSIX對這兩個術語的定義:
同步I/O操做:致使請求進程阻塞,直到I/O操做完成;
異步I/O操做:不致使請求進程阻塞。
好,下面我用個人語言來總結一下阻塞,非阻塞,同步,異步
阻塞,非阻塞:進程/線程要訪問的數據是否就緒,進程/線程是否須要等待;
同步,異步:訪問數據的方式,同步須要主動讀寫數據,在讀寫數據的過程當中仍是會阻塞;異步只須要I/O操做完成的通知,並不主動讀寫數據,由操做系統內核完成數據的讀寫。
以上內容轉載至http://yaocoder.blog.51cto.com/2668309/1308899
下面是我在知乎上看到的例子的解釋~~~
老張愛喝茶,廢話不說,煮開水。
出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。
1 老張把水壺放到火上,立等水開。(同步阻塞)
老張以爲本身有點傻
2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞)
老張仍是以爲本身有點傻,因而變高端了,買了把會響笛的那種水壺。水開以後,能大聲發出嘀~~~~的噪音。
3 老張把響水壺放到火上,立等水開。(異步阻塞)
老張以爲這樣傻等意義不大
4 老張把響水壺放到火上,去客廳看電視,水壺響以前再也不去看它了,響了再去拿壺。(異步非阻塞)
老張以爲本身聰明瞭。
所謂同步異步,只是對於水壺而言。
普通水壺,同步;響水壺,異步。
雖然都能幹活,但響水壺能夠在本身完工以後,提示老張水開了。這是普通水壺所不能及的。
同步只能讓調用者去輪詢本身(狀況2中),形成老張效率的低下。
所謂阻塞非阻塞,僅僅對於老張而言。
立等的老張,阻塞;看電視的老張,非阻塞。
狀況1和狀況3中老張就是阻塞的,媳婦喊他都不知道。雖然3中響水壺是異步的,可對於立等的老張沒有太大的意義。因此通常異步是配合非阻塞使用的,這樣才能發揮異步的效用。
做者:愚抄連接:http://www.zhihu.com/question/19732473/answer/23434554來源:知乎著做權歸做者全部,轉載請聯繫做者得到受權。