概念辨析
同步(Synchronous)和非同步(Asynchronous)
同步和非同步關注的是任務完成的順序和時間:
-
同步操作意味著在執行某個任務時,必須等待這個任務完成後才能繼續執行下一個任務。這通常會導致執行執行緒在等待任務完成時處於阻塞狀態。
-
非同步操作允許執行執行緒在發起一個任務後,不需要等待它完成就可以繼續執行後續任務。非同步操作通常透過回撥、事件、訊號等機制來通知呼叫者任務已完成。
-
- 狀態:即監聽被呼叫者的狀態(輪詢),呼叫者需要每隔一定時間檢查一次,效率會很低。
- 通知:當被呼叫者執行完成後,發出通知告知呼叫者,無需消耗太多效能。
- 回撥:與通知類似,當被呼叫者執行完成後,會呼叫呼叫者提供的回撥函式。
並行(Parallel)和併發(Concurrent)
並行和併發關注的是任務如何在處理器上執行:
- 並行指的是多個任務在多個處理器上同時執行。在並行執行中,任務之間是完全獨立的,可以同時進行,從而提高效率。
- 併發指的是多個任務在一個或多個處理器上交替執行。在單個處理器系統中,雖然任務看起來是同時執行的,但實際上處理器在不同任務間快速切換,給人一種同時執行的錯覺。
阻塞(Blocking)和非阻塞(Non-blocking)
阻塞和非阻塞關注的是在等待任務完成時,執行緒的狀態和行為:
- 阻塞操作是指在等待操作完成時,當前執行緒會被掛起。例如,一個阻塞的I/O呼叫會導致請求它的執行緒停止執行,直到I/O操作完成。
- 非阻塞操作是指即使操作尚未完成,當前執行緒也不會被掛起。非阻塞操作允許執行緒繼續執行並定期檢查操作是否完成。
阻塞非阻塞與同步非同步的區別
同步/非同步關注的是訊息通知的機制,而阻塞/非阻塞關注的是程式(執行緒)等待訊息通知時的狀態。
以小明下載檔案打個比方,從這兩個關注點來再次說明這兩組概念,希望能夠更好的促進大家的理解。
同步阻塞:小明一直盯著下載進度條,到 100% 的時候就完成。
- 同步體現在:等待下載完成通知;
- 阻塞體現在:等待下載完成通知過程中,不能做其他任務處理;
同步非阻塞:小明提交下載任務後就去幹別的,每過一段時間就去瞄一眼進度條,看到 100% 就完成。
- 同步體現在:等待下載完成通知,但是要在;
- 非阻塞體現在:等待下載完成通知過程中,去幹別的任務了,只是時不時會瞄一眼進度條;【小明必須要在兩個任務間切換,關注下載進度】
非同步阻塞:小明換了個有下載完成通知功能的軟體,下載完成就“叮”一聲。不過小明仍然一直等待“叮”的聲音(看起來很傻,不是嗎)。
- 非同步體現在:下載完成“叮”一聲通知;
阻塞體現在:等待下載完成“叮”一聲通知過程中,不能做其他任務處理;
非同步非阻塞:仍然是那個會“叮”一聲的下載軟體,小明提交下載任務後就去幹別的,聽到“叮”的一聲就知道完成了。
- 非同步體現在:下載完成“叮”一聲通知;
- 非阻塞體現在:等待下載完成“叮”一聲通知過程中,去幹別的任務了,只需要接收“叮”聲通知即可;【軟體處理下載任務,小明處理其他任務,不需關注進度,只需接收軟體“叮”聲通知,即可】
也就是說,同步/非同步是“下載完成訊息”通知的方式(機制),而阻塞/非阻塞則是在等待“下載完成訊息”通知過程中的狀態(能不能幹其他任務),在不同的場景下,同步/非同步、阻塞/非阻塞的四種組合都有應用。
所以,綜上所述,同步和非同步僅僅是關注的訊息如何通知的機制,而阻塞與非阻塞關注的是等待訊息通知時的狀態。也就是說,同步的情況下,是由處理訊息者自己去等待訊息是否被觸發,而非同步的情況下是由觸發機制來通知處理訊息者,所以在非同步機制中,處理訊息者和觸發機制之間就需要一個連線的橋樑:
在小明的例子中,這個橋樑就是軟體“叮”的聲音。
同步/非同步與阻塞/非阻塞效率
1 同步阻塞形式
效率是最低的,
拿上面的例子來說,就是你專心等待下載完成,什麼別的事都不做。
實際程式中:就是未對fd 設定O_NONBLOCK標誌位的read/write 操作;
2 非同步阻塞形式
非同步操作是可以被阻塞住的,只不過它不是在處理訊息時阻塞,而是在等待訊息通知時被阻塞。
比如select 函式,假如傳入的最後一個timeout引數為NULL,那麼如果所關注的事件沒有一個被觸發,程式就會一直阻塞在這個select 呼叫處。
3 同步非阻塞形式
實際上是效率低下的,
想象一下你一邊幹別的事情一邊還需要抬頭看下載完成沒有,如果把幹別的事情和觀察下載完成情況的位置看成是程式的兩個操作的話,這個程式需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的。
很多人會寫阻塞的read/write 操作,但是別忘了可以對fd設定O_NONBLOCK 標誌位,這樣就可以將同步操作變成非阻塞的了。
4 非同步非阻塞形式
效率更高,
因為等待下載完成是你(等待者)的事情,而通知你則是電腦(訊息觸發機制)的事情,程式沒有在兩種不同的操作中來回切換。
至此,關於程序執行緒、同步非同步、阻塞非阻塞、併發並行已經講的差不多了,有講的不好的地方請大佬指出。同時也謝謝網上大佬的文章幫助我理解了這些概念。
參考來源
https://cloud.tencent.com/developer/article/1592939