如何理解阻塞、非阻塞與同步、非同步的區別?

平時談論阻塞、非阻塞和同步、非同步時,對概念總是理解的不是那麼清晰。今天抽空查了一下資料,把查到的資料整理一下。

主要參考知乎上的回答:怎樣理解阻塞非阻塞與同步非同步的區別? - 網路編程 - 知乎

一、同步與非同步

同步與非同步關注的是消息通信機制(synchronous communication/ asynchronous communication)。所謂同步,就是在發出一個調用時,在沒有得到結果之前,該調用就不反回。但是一旦調用返回,就得到返回值了。換句話說,就是由調用者主動等待這個調用的結果。

而非同步則是相反,調用在發出之後,這個調用就直接返回了,所以就沒有返回結果。換句話說,當一個非同步過程調用發出後,調用者不會立刻得到結果。而是在調用發出之後,被調用者通過「狀態」、「通知」、「回調」三種途徑通知調用者。

可以使用哪一種途徑依賴於被帶調用者的實現,除非被調用者提供多種選擇,否則不受調用者控制。如果被調用者用狀態來通知,那麼調用者就需要每隔一定時間檢查一次,效率就很低。如果使用通知和回調的方式,效率則很高。因為被調用者幾乎不需要做額外的操作。

舉個例子:

你打電話問書店老闆有沒有《分散式系統》這本書,如果是同步通信機制,書店老闆會說,你稍等,」我查一下",然後開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。

而非同步通信機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,然後直接掛電話了(不返回結果)。然後查好了,他會主動打電話給你。在這裡老闆通過「回電」這種方式來回調。

二、回調函數

上面提到,回調是非同步調用的一種實現方式。那麼什麼是回調函數呢?

  • 概念

回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。

  • 舉個例子

概念不是太好理解,我們舉個例子。

沿用上面買書的例子,你的電話號碼就叫回調函數,你把電話留給書店老闆就叫登記回調函數,書店老闆查好了叫做觸發了回調關聯的事件,老闆給你打電話叫做調用回調函數。你接電話叫做響應回調事件。

  • 代碼實現(僅為了說明回調函數)

# coding=utf-8nimport timennndef call_back(): # 回調函數n print "我是回調函數"nnndef call_later(call_time, callback):n # 沉睡call_time後,調用回調函數n time.sleep(call_time) n callback()nnif __name__ == __main__:n call_later(10, call_back) # 登記回調函數n

三、阻塞與非阻塞

阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態。

阻塞調用是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之後才會返回。非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程。

接著上面的例子:

你打電話問書店老闆有沒有《分散式系統》這本書,你如果是阻塞式調用,你會一直把自己「掛起」,直到得到這本書有沒有的結果,如果是非阻塞式調用,你不管老闆有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鐘check一下老闆有沒有返回結果。

四、故事描述

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

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

  1. 老張把水壺放到火上,立等水開。(同步阻塞)老張覺得自己有點傻。
  2. 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞)。

  3. 老張還是覺得自己有點傻,於是變高端了,買了把會響笛的那種水壺。水開之後,能大聲發出嘀~~~~的噪音。
  4. 老張把響水壺放到火上,立等水開。(非同步阻塞)。

  5. 老張覺得這樣傻等意義不大,老張把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(非同步非阻塞)。
  • 所謂同步非同步,只是對於水壺而言。普通水壺,同步;響水壺,非同步。雖然都能幹活,但響水壺可以在自己完工之後,提示老張水開了。這是普通水壺所不能及的。同步只能讓調用者去輪詢自己(情況2中),造成老張效率的低下。
  • 所謂阻塞非阻塞,僅僅對於老張而言。立等的老張,阻塞;看電視的老張,非阻塞。

    情況1和情況3中老張就是阻塞的,媳婦喊他都不知道。雖然3中響水壺是非同步的,可對於立等的老張沒有太大的意義。所以一般非同步是配合非阻塞使用的,這樣才能發揮非同步的效用。

推薦閱讀:

網路遊戲中子彈與單位的命中判定問題
深入理解並發/並行,阻塞/非阻塞,同步/非同步

TAG:同步 | 异步 | 非阻塞 |