今天讀了一本計算機底層的書,書中詳細闡述了同步與異步在系統底層方面的處理方法。這篇文章就來討論一下什么是同步,什么是異步,它們在編程中到底意味著什么。要想寫出高性能高并發的代碼,這是很關鍵的基礎。
相信很多同學在開始接觸到同步異步這兩個詞的時候大腦一片懵逼,沒錯,這兩個看上去很像實際上也很像的兩個詞,曾經也讓本人深度困擾,以至于夜不能寐。這兩個詞具體的含義到底是什么呢?
先來看一個咱們身邊常見的場景:
美好的一天從打卡開始,現在起你化身為
苦逼程序員
假設現在老板安排給你一個十分緊急的開發任務,讓你下班前必須整出來(萬惡的資本主義)。為了確保能夠完成任務,老板就坐在你旁邊看著。
你心里肯定一萬頭羊駝奔騰而過:“***,這得多閑,干嘛盯著老子,你就不能去干別的?我還怎么摸魚”
老板仿佛看透你的小心思:“我就在這等著,你寫完前我哪兒都不去,別墨跡抓緊整。”
在上面這個例子中,老板交代給你任務后什么都不做一直等待直到你完成這就是同步的形式。
第二天老板又分配給你新的任務:“小伙子能力真不錯,不用多久你就可以升職加薪、當上總經理、出任CEO、迎娶白富美、走上人生巔峰了。不要激動,來,先把今天這個任務完成,不著急,寫完告訴我一聲就行。”
老板說完就回去刷抖音了,而你經過四五個小時的努力摸魚后,簡簡單單就碼完了:“老板,我寫完了,你來瞅瞅。”
這個例子中老板安排完以后就干別的事情了,而你寫完了告訴老板任務完成,這種就屬于異步的概念。
異步相對于同步最明顯的不同就是你工作的時候老板在刷劇,這兩件事情同時發生,因此從理論上講異步的效率要高于同步,對大多數場景而言是這樣的。
so,so,so!果真遇到在身后盯著寫代碼的老板,三十六計走為上策!
下面這個場景用來理解同步異步更為鮮明
打電話vs發郵件
作為苦逼程序員不能只會埋頭搬磚,工作中總得與客戶交流,最常用的方式就是打電報。。。啊不,是打電話。
通常我們打電話都是一個人說另一個人聽,對方講話的時候我方需要等待,等對方講完再接著說,而且每一步都依賴之前的講話。這里的重點是產生了等待,不可避免地等待,這種方式就是同步的特點。
作為搬磚碼農,另外一種比較常用的方式就是發郵件,尤其是在公司內部。沒有人為了等你的郵件什么都不做,他可以摸摸魚,充下電,上個廁所等等。同樣的你發完郵件也不需要一直等著對方的回復,這期間可以做其他有意義的事情。
在這種方式中,寫郵件和收件人摸魚這兩件事情同時發生著,雙方都不需要等待,兩件事情也不存在依賴,這就是異步的方式。
編程中的同步
現在回到編程的主題,上面場景展示了生活中的同步異步的意義,那么在程序開發中又該怎樣理解呢?
一般情況下函數的調用都是這樣的
/**JAVAscript */
function A( ){
//等待函數b完成
function B( )
//繼續后面的運行
}
函數A調用函數B,那么在B完成前A都不會執行后續的代碼,就像這樣:
從上圖看到B執行期間A什么都不能做,這就是同步。
下面這段Node代碼就是采用同步的方式執行磁盤文件讀取,屬于阻塞式I/O
/**JavaScript */
import { readFileSync } from 'fs';
readFileSync('<directory>');//程序暫停運行,等待I/O返回數據
//文件讀取完成后繼續運行
同步編程對程序員是最好理解的,一步完成再做下一步,但代價就是在某些場景(例如I/O操作)下這種方式的效率不夠高效,因為任務沒法同時進行。
編程中的異步
有同步就有異步,在理解了前面的內容后相信很快就能掌握異步的要領。
一般來說在程序開發中,一些耗時比較高的任務都是采用異步的方式,例如磁盤讀寫,網絡數據收發,數據庫命令的執行等。同樣以磁盤文件讀取為例,使用異步函數即使文件還沒有讀取完畢后面的代碼也能執行。
/**javascript */
import { readFile } from 'fs';
readFile('<directory>', callback);//readFile函數立即返回
//不會阻塞程序的執行
//某個時間點文件讀取完成后執行callback回調
異步的重點在于調用函數后接下來的程序可以繼續和文件讀取同時執行,這就是高效之處。
然而,異步執行對程序員來說是一種負擔,無論在閱讀還是編寫上都不容易理解。
有的同學可能會問,同步的情況下可以得到函數的結果繼續執行,那么異步的時候又怎么知道函數執行完成了呢?
這里一分為二:
- 不需要關心結果,執行就ok
- 需要結果進行更多的操作
第一種無需討論,比較簡單。
第二種情況通常有兩種方式,一種是通知機制,任務完成后發送信號通知上一級,例如linux的signal方式。還有一種就是回調,就是我們常說的callback。
最后需要注意的是,并非所有的情況下異步就一定比同步高效,還要結合具體的業務或者I/O復雜程度來分析。但是不管何時何地,同步意味著雙方要相互等待,相互依賴,二異步則意味著雙方相互獨立,各行其道。希望這篇文章對大家理解這兩個重要的概念有所幫助。