Linux下阻塞與非阻塞IO

來源:互聯網
上載者:User

標籤:socket   伺服器   緩衝區   linux   用戶端   

    阻塞:顧名思義,就是指在執行裝置操作時若不能獲得資源則掛起操作,直到滿足可操作的條件後再進行操作,被掛起的進程進入休眠狀態,被從調度器的運行隊列移走,直到等待的條件滿足。

     非阻塞:就是反過來,進程在不能進行裝置操作時並不掛起,它或者放棄,或者不停的查詢,直到可以進行位置。

    650) this.width=650;" src="http://s3.51cto.com/wyfs02/M00/6D/CD/wKioL1VsKMKRPNOEAAFrmAaak10486.jpg" title="1b.jpg" alt="wKioL1VsKMKRPNOEAAFrmAaak10486.jpg" />

Socket編程中,阻塞與非阻塞的區別:

阻塞:一般的I/O操作可以在建立的流中運用.在伺服器回應前它等待用戶端發送一個空白的行.當會話結束時,伺服器關閉流和用戶端socket. 如果在隊列中沒有請示將會出現什麼情況呢?那個方法將會等待一個的到來.這個行為叫阻塞.accept()方法將會阻塞伺服器線程直到一個呼叫到來.當5個串連處理完閉之後,伺服器退出.任何的在隊列中的呼叫將會被取消.

非阻塞:非阻塞通訊端是指執行此通訊端的網路調用時,不管是否執行成功,都立即返回。比如調用recv()函數讀取網路緩衝區中資料,不管是否讀到資料都立即返回,而不會一直掛在此函數調用上。在實際Windows網路通訊軟體開發中,非同步非阻塞通訊端是用的最多的。平常所說的C/S(用戶端/伺服器)結構的軟體就是非同步非阻塞模式的。 
   
      具體機制就是上面所說的,簡明扼要的來說可以打個比方:
      你有數個同學來訪 <---> 有若干資料需要收取
      (1)你時不時的去門口看看,沒有看到你同學的話就回客廳等待,看到同學就接到客廳來 <---> 非阻塞模式,無論收到 資料與否都返回
      (2)你一直在門口等著你同學,接到後才回客廳 <---> 阻塞模式,接收到資料後才返回
 
    使用阻塞怎麼了?會帶來什麼後果?在什麼情況之下?對效能有影響嗎?:
    通訊端有兩種模式,阻塞模式與非阻塞模式。預設建立的為阻塞模式.
在blocking model 下:
    通訊端在IO時阻塞應用程式,就是說控制權不會返回給應用程式,也就是說程式執行到此代碼時會卡住。分兩種情況,1.send函數時,只有把要發送的資料下傳至TCP層,send這句代碼才繼續向下執行,此時可確認自己的資料已經在網路上傳輸了2.recv時,只有收到一定資料給應用程式緩衝區時,recv這行代碼才會向下執行。如果不想這樣做,可以使用多線程,或者選用其他網路IO模型。一般在做伺服器程式時,不會使用阻塞通訊端,效能低,資料吞吐率也不高。優點是此種模型編寫難度較低,可以用來做入門的學習之用。
非阻塞通訊端,IO會馬上返回.但在send時,如果SOCKET緩衝區已滿,會返回錯誤,使用WSAGetLastError會得到錯誤碼為WSAEWOULDBLOCK,意思是說在一個非阻塞的通訊端上,請求沒有完成。recv時如果SOCKET緩衝區沒有可以讀的資料,也會返回WSAEWOULDBLOCK.
 
  Socket 的模式大概分為這麼幾種:
1、阻塞式的,Socket操作都需要將線程掛起,等待核心完成後才能返回。
如: 調用connect=>進入核心=>Syn包=〉伺服器返回SYN ACK 包=〉connect返回。
=〉ACK包發往伺服器。
但一般來說,阻塞和非阻塞對於recv來說意義更大。
當在阻塞式的Socket上調用recv時,如果這時網路棧上沒有資料給你接收,那麼這時線程將
會掛起,直到有報文給你接收才返回。
這樣就造成你的應用程式在企圖接收資料時候,而網路棧上沒有資料的時候就會被鎖住。
有什麼辦法解決這個問題呢? 我們來介紹IO
2、 IO複用, 就是在企圖讀寫資料的時候先詢問下是否可讀寫,如果不能,可以去幹別的事情,不會造成死結。
但是假如我們有大量的串連需要去頻繁的查詢可讀寫狀態,每次查詢都會和核心互動。這樣會造成
效率低下。再介紹一種
3、 重疊IO. 就是一次查詢多個Socket的狀態。不用去來來回回的遍曆。
另外,
在windows socket api 中還有一種訊息機制,就是把Socket狀態通知到視窗。然後用訊息去處理。
對於重疊IO, 在windows上還有完成連接埠模型,他和重疊連接埠相比,不但能捕捉到IO事件, 而且核心已經替你完成了Socket IO, 比如read事件, 在核心通知你的時候,他已經幫你讀好資料了,並放在你指定的緩衝中(這裡是指在使用者態下,事先為每個Socket分配的記憶體)。
為什麼有這麼多socket模式呢? 哪個更好呢?
為什麼有,我不知道,可能是出於需求吧,
說說哪個更好?
孤立的來說,其實沒有哪個更好? 只有哪個更適合你的應用應用環境。
如: 阻塞式的比較簡單,方便,穩定。適合比較簡單的用戶端程式。
IO複用我認為它適合SocketIO操作比較少的情況。
重疊IO就適合高效能的伺服器的開發,另外完成連接埠是windows上比較公認的高效能伺服器的網路開發模型。當然, windows 的IOCP也有個壞處,就是需要大量的記憶體,應為前面說了他需要事先指定緩衝。不過高效能的 伺服器,一般都不用windows平台。
windows的訊息模型就比較適合有UI的應用程式。


Linux下阻塞與非阻塞IO

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.