異步和非阻塞之間的區別


看了不少關於阻塞、非阻塞、同步和異步文章,我覺得這篇http://www.toxingwang.com/linux-unix/linux-basic/1712.html是講得不錯的。

以下是這篇文章對於阻塞、非阻塞、同步異步的解釋

阻塞和非阻塞指的是執行一個操作是等操作結束再返回,還是馬上返回。

比如餐館的服務員為用戶點菜,當有用戶點完菜后,服務員將菜單給后台廚師,此時有兩種方式:

  • 第一種:就在出菜窗口等待,直到廚師炒完菜后將菜送到窗口,然后服務員再將菜送到用戶手中;
  • 第二種:等一會再到窗口來問廚師,某個菜好了沒?如果沒有先處理其他事情,等會再去問一次;

第一種就是阻塞方式,第二種則是非阻塞的。

  同步和異步又是另外一個概念,它是事件本身的一個屬性。還拿前面點菜為例,服務員直接跟廚師打交道,菜出來沒出來,服務員直接指導,但只有當廚師將菜送到服務員手上,這個過程才算正常完成,這就是同步的事件。同樣是點菜,有些餐館有專門的傳菜人員,當廚師炒好菜后,傳菜員將菜送到傳菜窗口,並通知服務員,這就變成異步的了。其實異步還可以分為兩種:帶通知的和不帶通知的。前面說的那種屬於帶通知的。有些傳菜員干活可能主動性不是很夠,不會主動通知你,你就需要時不時的去關注一下狀態。這種就是不帶通知的異步。

對於同步的事件,你只能以阻塞的方式去做。而對於異步的事件,阻塞和非阻塞都是可以的。非阻塞又有兩種方式:主動查詢和被動接收消息。被動不意味着一定不好,在這里它恰恰是效率更高的,因為在主動查詢里絕大部分的查詢是在做無用功。對於帶通知的異步事件,兩者皆可。而對於不帶通知的,則只能用主動查詢。

  但是對於非阻塞和異步的概念有點混淆,非阻塞只是意味着方法調用不阻塞,就是說作為服務員的你不用一直在窗口等,非阻塞的邏輯是"等可以讀(寫)了告訴你",但是完成讀(寫)工作的還是調用者(線程)服務員的你等菜到窗口了還是要你親自去拿。而異步意味這你可以不用親自去做讀(寫)這件事,你的工作讓別人(別的線程)來做,你只需要發起調用,別人把工作做完以后,或許再通知你,它的邏輯是“我做完了 告訴/不告訴 你”,他和非阻塞的區別在於一個是"已經做完"另一個是"可以去做"。

這也是NIO和AIO最大的區別,就是NIO在有通知時可以進行相關操作,而AIO有通知時則代表操作已經完成

再舉一個例子:

  去書店借一本書,同步就是我要親自到書店,問老板有沒有這本書,阻塞就是老板查詢的時候(讀寫)我只能在那等着,老板找到書后把書交給我,這就是同步阻塞。

  我親自到書店借書,老板在找這本書的時候,我可以去干別的,然后每隔一段時間去問老板書找到了沒有,也可以等老板找到書以后通知我,這就是同步非阻塞。

  我想借本書,找個人幫我去借,借到書以后再通知我,這就是異步,我只發起調用,但是本身並不參與這個事件,而是讓別的線程去做這個事。

  同步與異步是對應的,它們是線程之間的關系,兩個線程之間要么是同步的,要么是異步的。

  阻塞與非阻塞是對同一個線程來說的,在某個時刻,線程要么處於阻塞,要么處於非阻塞。

  幫我借書的那個人有沒有借到書,我可以打電話問他(輪詢),也可以等他通知我,這是異步的通知;在借書的過程中借書的那個人可以輪詢的方式查看書是否已經找到(緩沖區有沒有數據),找到了你可以把它拿走,也可以等老板找到書后通知我,這是非阻塞的通知與輪詢。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM