在學習到python網路程式設計,socketserver.中,涉及到select的應用,由此了解到socket的setblocking模式,了解了socket有阻塞與非阻塞的區別,同時網上查詢了一下,感覺對非同步、同步的概念有些重疊,為此深入了解一下。
在linux網路io中涉及到如下模型:
(1)阻塞式io
(2)非阻塞式io
(3)io多路復用
(4)訊號驅動io
(5)非同步io
**阻塞式i/o模型:**預設情況下,所有套接字都是阻塞的。怎麼理解?先理解這麼個流程,乙個輸入操作通常包括兩個不同階段:
(1)等待資料準備好;
(2)從核心向程序複製資料。
對於乙個套接字上的輸入操作,第一步通常涉及等待資料從網路中到達。當所有等待分組到達時,它被複製到核心中的某個緩衝區。第二步就是把資料從核心緩衝區複製到應用程式緩衝區。 好,下面我們以阻塞套接字的recvfrom的的呼叫圖來說明阻塞
標紅的這部分過程就是阻塞,直到阻塞結束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操作完成的通知,並不主動讀寫資料,由作業系統核心完成資料的讀寫。
**同步:**執行乙個操作之後,等待結果,然後才繼續執行後續的操作。
非同步:執行乙個操作後,可以去執行其他的操作,然後等待通知再回來執行剛才沒執行完的操作。
**阻塞:**程序給cpu傳達乙個任務之後,一直等待cpu處理完成,然後才執行後面的操作。
**非阻塞:**程序給cpu傳達任我後,繼續處理後續的操作,隔斷時間再來詢問之前的操作是否完成。這樣的過程其實也叫輪詢。
阻塞、非阻塞、多路io復用,都是同步io,非同步必定是非阻塞的,所以不存在非同步阻塞和非同步非阻塞的說法。真正的非同步io需要cpu的深度參與。換句話說,只有使用者執行緒在操作io的時候根本不去考慮io的執行全部都交給cpu去完成,而自己只等待乙個完成訊號的時候,才是真正的非同步io。所以,拉乙個子執行緒去輪詢、去死迴圈,或者使用select、poll、epool,都不是非同步。
理解阻塞非阻塞與同步非同步
同步和非同步關注的是訊息通訊機制 synchronous communication asynchronous communication 所謂同步,就是在發出乙個 呼叫 時,在沒有得到結果之前,該 呼叫 就不返回。但是一旦呼叫返回,就得到返回值了。換句話說,就是由 呼叫者 主動等待這個 呼叫 的結...
同步 非同步,阻塞 非阻塞理解
由於同步非同步,阻塞非阻塞都學習了有一段時間了。慢慢了快忘了,所以乾脆趁著寒假把知識點都撿起來,寫出來。同步和非同步是一組概念,阻塞和非阻塞是一組概念。大家不要搞混了,不要把同步和阻塞等價,也不要把非同步和非阻塞等價 戲說不是胡說,改編不是亂編 滑稽 在剛開始理解的時候很容易搞混,我們這樣想,同步和...
阻塞與非阻塞 同步與非同步的理解
1 使用場景 1 阻塞與非阻塞的使用場景 i o 多執行緒。2 同步與非同步的使用場景 通訊,多執行緒。2 具體理解 在實際網路程式設計的環境中,一般是指執行緒的同步和非同步與io的阻塞與非阻塞,與系統底層的同步通訊與非同步通訊無關,多執行緒的阻塞即多執行緒的同步,多執行緒的非阻塞即多執行緒的非同步...