1. 程式人生 > >同步與異步、阻塞與非阻塞

同步與異步、阻塞與非阻塞

阻塞與非阻塞 就會 結束 檢查 通信機制 得到 node 分布 好書


“阻塞”與"非阻塞"與"同步"與“異步"不能簡單的從字面理解,提供一個從分布式系統角度的回答。
1.同步與異步
同步和異步關註的是消息通信機制 (synchronous communication/ asynchronous communication)
所謂同步,就是在發出一個*調用*時,在沒有得到結果之前,該*調用*就不返回。但是一旦調用返回,就得到返回值了。
換句話說,就是由*調用者*主動等待這個*調用*的結果。

而異步則是相反,*調用*在發出之後,這個調用就直接返回了,所以沒有返回結果。換句話說,當一個異步過程調用發出後,調用者不會立刻得到結果。而是在*調用*發出後,*被調用者*通過狀態、通知來通知調用者,或通過回調函數處理這個調用。

典型的異步編程模型比如Node.js

舉個通俗的例子:
你打電話問書店老板有沒有《分布式系統》這本書,如果是同步通信機制,書店老板會說,你稍等,”我查一下",然後開始查啊查,等查好了(可能是5秒,也可能是一天)告訴你結果(返回結果)。
而異步通信機制,書店老板直接告訴你我查一下啊,查好了打電話給你,然後直接掛電話了(不返回結果)。然後查好了,他會主動打電話給你。在這裏老板通過“回電”這種方式來回調。

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

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

還是上面的例子,
你打電話問書店老板有沒有《分布式系統》這本書,你如果是阻塞式調用,你會一直把自己“掛起”,直到得到這本書有沒有的結果,如果是非阻塞式調用,你不管老板有沒有告訴你,你自己先一邊去玩了, 當然你也要偶爾過幾分鐘check一下老板有沒有返回結果。
在這裏阻塞與非阻塞與是否同步異步無關。跟老板通過什麽方式回答你結果無關。


A.概念

阻塞非阻塞: 請求不能立即得到應答,需要等待,那就是阻塞;否則可以理解為非阻塞。

同步異步: 某業務需要甲乙甚至多方合作的時候,

  1. 總是按照“甲方請求一次,乙方應答一次”這樣的有序序列處理業務,只有當“一次請求一次應答”的過程結束才可以發生下一次的“一次請求一次應答”,那麽就說他們采用的是同步。(同步IO中
    對同一個描述符的操作必須是有序的
  2. 如果甲方只要有需要,就會發送請求,不管上次請求有沒有得到乙方應答。而乙方只要甲方有請求就會接受,不是等這次請求處理完畢再接受甲方新請求。這樣請求應答分開的序列,就可以認為是異步。異步情況下,請求和應答不需要一致進行,可能甲方後請求的業務,卻先得到乙方的應答。同步是線性的,而異步可以認為是並發的。(異步IO中,異步IO可以允許多方同時對同一個描述符發送IO請求,或者一次發多個請求,當然有機制保證如何區分這些請求,

舉個例子:

  1. 我去買一本書,立即買到了,或者沒有就走了,這就是非阻塞;(編程中設置IO成非阻塞,返回後再去檢查描述符,或者等待通知,然後再去讀取。相當於老板告訴我可以先忙點別的,過一會再來問問,或者老板通知我。但期間這個窗口(文件描述符)別人是用不了的)("立即買到了"在IO中也需要等待,不能算非阻塞IO)
  2. 如果恰好書店沒有,我就等一直等到書店有了這本書買到了才走,這就是阻塞;而排在我後面的人呢只有我買到了書後才能再買書了。
  3. 如果書店恰好沒有,我就告訴書店老板,書來了告訴我一聲讓我來取或者直接送到我家,然後我就走了,去做別的事了,這就是異步。這時候如果很多人來買書,都是老板登記一下完事。 (從IO角度來說,“告訴我來取”,這個近似於信號驅動IO,不能算異步IO。必須書送到我家才算是異步,如果不送到我家,我想看這本書之前,終究還是需要我跑一趟)
  4. 前面兩種情況,非阻塞和阻塞都可以稱為同步。

同步與異步、阻塞與非阻塞