也談阻塞 非阻塞 同步 非同步

2022-08-05 04:48:16 字數 2112 閱讀 6349

最近在招聘中,聊到基礎的網路程式設計的時候,發現不少人對bio、nio、aio等理解非常模糊,覺得有必要寫文章來糾正下很多人的誤解。 

在談這些之前,非常有必要先介紹下unix 5種io模型: 

阻塞:

阻塞是最常用的io模型,預設情況下所有的檔案操作都是阻塞的。以套接字程式設計為例。在程序空間中呼叫recvfrom,其系統呼叫直到資料報文到達且被拷貝到應用程式程序的快取區(或者發生錯誤)後才返回,期間一直在等待。程序在從呼叫recvfrom開始到它返回的整段時間內是被阻塞的。有一張很經典的圖: 

非阻塞:

呼叫recvfrom從應用層到核心的過程中,如果該緩衝區沒有資料的話,則直接返回乙個ewouldblock的錯誤,一般會輪詢的進行檢查狀態,看核心空間有沒有資料來。直到有資料,最後完成拷貝。如下圖: 

io多路復用:

linux系統提供的select/poll/epoll,程序將乙個或者多個fd(檔案描述符)傳遞給乙個或者多個poll/select系統呼叫,阻塞在select。select和poll可以幫助偵聽很多的fd是否準備就緒。但是,select和poll是順序掃瞄去檢查fd的就緒狀態,效率比較低,而且支援的fd數量有限(沒記錯的話,預設好像是1024還是2048,具體記不清)。而epoll是通過事件驅動的方式,當有fd準備就緒的時候,立即**函式rollback。如圖: 

談到epoll,不得不提乙個經典的問題,apache和nginx的對比,為什麼nginx比apache效率高很多,這就是根本的原因。 

訊號驅動:

這種模型在實際應用的非常少,這裡不做過多介紹,可以看圖: 

非同步:

告知核心啟動某個操作,並讓核心在整個操作完成後(包括將資料從核心空間拷貝到自己的緩衝區)通知。非同步io的主要特點是完成操作後主動通知。如圖: 

好,上面的可能有點抽象。下面用通俗點的語言來總結一下阻塞,非阻塞,同步,非同步。

阻塞,非阻塞:程序/執行緒要訪問的資料是否就緒,程序/執行緒是否需要等待; 

同步,非同步:訪問資料的方式,同步需要主動讀寫資料,在讀寫資料的過程中還是會阻塞; 

非同步只需要i/o操作完成的通知,並不主動讀寫資料,由作業系統核心完成資料的讀寫。 

再舉個網上流傳的,非常容易理解的例子: 

老張愛喝茶,廢話不說,煮開水。 

出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。 

1 老張把水壺放到火上,立等水開。(同步阻塞)老張覺得自己有點傻 

2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞) 

老張還是覺得自己有點傻,於是變高階了,買了把會響笛的那種水壺。水開之後,能大聲發出嘀~~~~的噪音。 

3 老張把響水壺放到火上,立等水開。(非同步阻塞)老張覺得這樣傻等意義不大 

4 老張把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(非同步非阻塞)老張覺得自己聰明了。 

所謂同步非同步,只是對於水壺而言。普通水壺,同步;響水壺,非同步。雖然都能幹活,但響水壺可以在自己完工之後,提示老張水開了。這是普通水壺所不能及的。 

同步只能讓呼叫者去輪詢自己(情況2中),造成老張效率的低下。所謂阻塞非阻塞,僅僅對於老張而言。立等的老張, 

阻塞;看電視的老張,非阻塞。情況1和情況3中老張就是阻塞的,媳婦喊他都不知道。 

雖然3中響水壺是非同步的,可對於立等的老張沒有太大的意義。所以一般非同步是配合非阻塞使用的,這樣才能發揮非同步的效用。

也談阻塞 非阻塞 同步 非同步

最近在招聘中,聊到基礎的網路程式設計的時候,發現不少人對bio nio aio等理解非常模糊,覺得有必要寫文章來糾正下很多人的誤解。在談這些之前,非常有必要先介紹下unix 5種io模型 阻塞 阻塞是最常用的io模型,預設情況下所有的檔案操作都是阻塞的。以套接字程式設計為例。在程序空間中呼叫recv...

阻塞,非阻塞,非同步,同步

之前一直對這個概念理不太清楚,今天看到一篇文章感覺不錯 本文 老張愛喝茶,廢話不說,煮開水。出場人物 老張,水壺兩把 普通 水壺,簡稱水壺 會響的水壺,簡稱響水壺 1 老張把水壺放到火上,立等水開。同步阻塞 老張覺得自己有點傻 2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。同步非阻...

同步 非同步 阻塞 非阻塞

故事 老王燒開水。出場人物 老張,水壺兩把 普通水壺,簡稱水壺 會響的水壺,簡稱響水壺 老王想了想,有好幾種等待方式 1.老王用水壺煮水,並且站在那裡,不管水開沒開,每隔一定時間看看水開了沒。同步阻塞 老王想了想,這種方法不夠聰明。2.老王還是用水壺煮水,不再傻傻的站在那裡看水開,跑去寢室上網,但是...