從小白到高手,你需要理解同步與異步

在這篇文章中我們來討論一下到底什么是同步根竿,什么是異步陵像,以及在編程中這兩個概念到底意味著什么,這些是進一步掌握高性能寇壳、高并發(fā)技術(shù)的基礎(chǔ),因此非常關(guān)鍵妻怎。

相信很多同學(xué)遇到同步異步這兩個詞的時候大腦瞬間就像紅綠燈失靈的十字路口一樣陷入一片懵逼的狀態(tài):

mengbi

是的壳炎,這兩個看上去很像實際上也很像的詞匯給博主造成過很大的困擾,這兩個詞背后所代表的含義到底是什么呢逼侦?

我們先從工作場景講起匿辩。

苦逼程序員

假設(shè)現(xiàn)在老板分配給了你一個很緊急并且很重要的任務(wù),讓你下班前必須寫完(萬惡的資本主義)榛丢。為了督促進度铲球,老板搬了個椅子坐在一邊盯著你寫代碼。

你心里肯定已經(jīng)罵上了“WTF晰赞,你有這么閑嗎稼病?盯著老子选侨,你就不能去干點其他事情嗎?”

老板仿佛接收到了你的腦電波一樣:“我就在這等著然走,你寫完前我哪也不去援制,廁所也不去”

1600911423466

這個例子中老板交給你任務(wù)后就一直等待什么都不做直到你寫完,這個場景就是所謂的同步芍瑞。

第二天晨仑,老板又交給了你一項任務(wù)。

不過這次就沒那么著急啦拆檬,這次老板輕描淡寫“小伙子可以啊洪己,不錯不錯,你再努力干一年竟贯,明年我就財務(wù)自由了答捕,今天的這個任務(wù)不著急,你寫完告訴我一聲就行”澄耍。

這次老板沒有盯著你寫代碼而是轉(zhuǎn)身刷視頻去了噪珊,你寫完后簡單的和老板報告了一聲“我寫完了”。

1600911037338

這個例子老板交代完任務(wù)就去忙其它事情齐莲,你完成任務(wù)后簡單的告訴老板任務(wù)完成痢站,這就是所謂的異步。

值得注意的是选酗,在異步這種場景下重點是在你寫代碼的同時老板在自己刷劇阵难,這兩件事在同時進行因此這就是為什么一般來說異步比同步高效的本質(zhì)所在芒填,不管同步異步應(yīng)用在什么場景下呜叫。

因此,我們可以看到同步這個詞往往和任務(wù)的“依賴”殿衰、“關(guān)聯(lián)”朱庆、“等待”等關(guān)鍵詞相關(guān),而異步往往和任務(wù)的“不依賴”闷祥,“無關(guān)聯(lián)”娱颊,“無需等待”,“同時發(fā)生”等關(guān)鍵詞相關(guān)凯砍。

By the way箱硕,如果遇到一個在身后盯著你寫代碼的老板,三十六計走為上策悟衩。

打電話與發(fā)郵件

作為一名苦逼的程序員是不能只顧埋頭搬磚的剧罩,平時工作中的溝通免除不了,其中一種高效的溝通方式是吵架座泳。惠昔。幕与。啊不,是電話舰罚。

email

通常打電話時都是一個人在說另一個人聽纽门,一個人在說的時候另一個人等待,等另一個人說完后再接著說营罢,因此在這個場景中你可以看到赏陵,“依賴”、“關(guān)聯(lián)”饲漾、“等待”這些關(guān)鍵詞出現(xiàn)了蝙搔,因此打電話這種溝通方式就是所謂的同步。

1600923556187

另一種碼農(nóng)常用的溝通方式是郵件考传。

郵件是另一種必不可少溝通方式吃型,因為沒有人傻等著你寫郵件什么都不做,因此你可以慢慢悠悠的寫僚楞,當(dāng)你在寫郵件時收件人可以去做一些像摸摸魚啊勤晚、上個廁所、和同時抱怨一下為什么十一假期不放兩周之類有意義的事情泉褐。

同時當(dāng)你寫完郵件發(fā)出去后也不需要干巴巴的等著對方什么都不做赐写,你也可以做一些像摸魚之類這樣有意義的事情。

1600923768618

在這里膜赃,你寫郵件別人摸魚挺邀,這兩件事又在同時進行,收件人和發(fā)件人都不需要相互等待跳座,發(fā)件人寫完郵件的時候簡單的點個發(fā)送就可以了端铛,收件人收到后就可以閱讀啦,收件人和發(fā)件人不需要相互依賴疲眷、不需要相互等待禾蚕。

你看,在這個場景下“不依賴”狂丝,“無關(guān)聯(lián)”夕膀,“無需等待”這些關(guān)鍵詞就出現(xiàn)了,因此郵件這種溝通方式就是異步的美侦。

同步調(diào)用

現(xiàn)在終于回到編程的主題啦。

既然現(xiàn)在我們已經(jīng)理解了同步與異步在各種場景下的意義(I hope so)魂奥,那么對于程序員來說該怎樣理解同步與異步呢菠剩?

我們先說同步調(diào)用,這是程序員最熟悉的場景耻煤。

一般的函數(shù)調(diào)用都是同步的具壮,就像這樣:

funcA() {
    // 等待函數(shù)funcB執(zhí)行完成
    funcB();
    
    // 繼續(xù)接下來的流程
}

funcA調(diào)用funcB准颓,那么在funcB執(zhí)行完前,funcA中的后續(xù)代碼都不會被執(zhí)行棺妓,也就是說funcA必須等待funcB執(zhí)行完成攘已,就像這樣:

1600925448485

從上圖中我們可以看到,在funcB運行期間funcA什么都做不了怜跑,這就是典型的同步样勃。

注意,一般來說性芬,像這種同步調(diào)用峡眶,funcA和funcB是運行在同一個線程中的,這是最為常見的情況植锉。

但值得注意的是辫樱,即使運行在兩個不能線程中的函數(shù)也可以進行同步調(diào)用,像我們進行IO操作時實際上底層是通過系統(tǒng)調(diào)用(關(guān)于系統(tǒng)調(diào)用請參考《程序員應(yīng)如何理解系統(tǒng)調(diào)用》)的方式向操作系統(tǒng)發(fā)出請求的俊庇,比如磁盤文件讀仁ㄊ睢:

read(file, buf);

這就是我們在《讀取文件時,程序經(jīng)歷了什么》中描述的阻塞式I/O辉饱,在read函數(shù)返回前程序是無法繼續(xù)向前推進的

read(file, buf);
// 程序暫停運行搬男,
// 等待文件讀取完成后繼續(xù)運行

如圖所示:

1600925867319

只有當(dāng)read函數(shù)返回后程序才可以被繼續(xù)執(zhí)行。

當(dāng)然鞋囊,這也是同步調(diào)用止后,但是和上面的同步調(diào)用不同的是,函數(shù)和被調(diào)函數(shù)運行在不同的線程中溜腐。

因此我們可以得出結(jié)論译株,同步調(diào)用和函數(shù)與被調(diào)函數(shù)是否運行在同一個線程是沒有關(guān)系的

在這里我們還要再次強調(diào)挺益,同步方式下函數(shù)和被調(diào)函數(shù)無法同時進行歉糜。

同步編程對程序員來說是最自然最容易理解的。

但容易理解的代價就是在一些場景下望众,注意匪补,是在某些場景不是所有場景哦,同步并不是高效的烂翰,因為任務(wù)沒有辦法同時進行夯缺。

接下來我們看異步調(diào)用。

異步調(diào)用

有同步調(diào)用就有異步調(diào)用甘耿。

關(guān)于重要的異步調(diào)用踊兜,關(guān)注公眾號“碼農(nóng)的荒島求生”并回復(fù)“async”你就知道了。

同步 vs 異步

我們以常見的Web服務(wù)來舉例說明這一問題佳恬。

一般來說Web Server接收到用戶請求后會有一些典型的處理邏輯捏境,最常見的就是數(shù)據(jù)庫查詢(當(dāng)然于游,你也可以把這里的數(shù)據(jù)庫查詢換成其它I/O操作,比如磁盤讀取垫言、網(wǎng)絡(luò)通信等)贰剥,在這里我們假定處理一次用戶請求需要經(jīng)過步驟A、B筷频、C然后讀取數(shù)據(jù)庫蚌成,數(shù)據(jù)庫讀取完成后需要經(jīng)過步驟D、E截驮、F笑陈,就像這樣:

# 處理一次用戶請求需要經(jīng)過的步驟:

A;
B;
C;
數(shù)據(jù)庫讀取;
D;
E葵袭;
F涵妥;

其中步驟A、B坡锡、C和D蓬网、E、F不需要任何I/O鹉勒,也就是說這六個步驟不需要讀取文件帆锋、網(wǎng)絡(luò)通信等,涉及到I/O操作的只有數(shù)據(jù)庫查詢這一步禽额。

一般來說這樣的Web Server有兩個典型的線程:主線程和數(shù)據(jù)庫處理線程锯厢,注意,這討論的只是典型的場景脯倒,具體業(yè)務(wù)實際上可會有差別实辑,但這并不影響我們用兩個線程來說明問題。

首先我們來看下最簡單的實現(xiàn)方式藻丢,也就是同步剪撬。

這種方式最為自然也最為容易理解:

// 主線程
main_thread() {
    A;
    B;
    C;
    發(fā)送數(shù)據(jù)庫查詢請求;
    D;
    E;
    F;
}

// 數(shù)據(jù)庫線程
DataBase_thread() {
    while(1) {
        數(shù)據(jù)庫讀取;
    }
}

這就是最為典型的同步方法,主線程在發(fā)出數(shù)據(jù)庫查詢請求后就會被阻塞而暫停運行悠反,直到數(shù)據(jù)庫查詢完畢后面的D残黑、E、F才可以繼續(xù)運行斋否,就像這樣:

1600994106960

從圖中我們可以看到梨水,主線程中會有“空隙”,這個空隙就是主線程的“休閑時光”茵臭,主線程在這段休閑時光中需要等待數(shù)據(jù)庫查詢完成才能繼續(xù)后續(xù)處理流程冰木。

在這里主線程就好比監(jiān)工的老板,數(shù)據(jù)庫線程就好比苦逼搬磚的程序員,在搬完磚前老板什么都不做只是緊緊的盯著你踊沸,等你搬完磚后才去忙其它事情。

顯然社证,高效的程序員是不能容忍主線程偷懶的逼龟。

是時候祭出大殺器了,這是什么大殺器呢追葡,關(guān)于這個問題的答案關(guān)注公眾號“碼農(nóng)的荒島求生”并回復(fù)“回調(diào)”二字你就知道答案了腺律。

總結(jié)

在這篇文章中我們從各種場景分析了同步與異步這兩個概念,但是不管在什么場景下宜肉,同步往往意味著雙方要相互等待匀钧、相互依賴,而異步意味著雙方相互獨立谬返、各行其是之斯。希望本篇能對大家理解這兩個重要的概念有所幫助。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遣铝,一起剝皮案震驚了整個濱河市佑刷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酿炸,老刑警劉巖瘫絮,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異填硕,居然都是意外死亡麦萤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門扁眯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壮莹,“玉大人,你說我怎么就攤上這事恋拍《饪祝” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵施敢,是天一觀的道長周荐。 經(jīng)常有香客問我,道長僵娃,這世上最難降的妖魔是什么概作? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮默怨,結(jié)果婚禮上讯榕,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好愚屁,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布济竹。 她就那樣靜靜地躺著,像睡著了一般霎槐。 火紅的嫁衣襯著肌膚如雪送浊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天丘跌,我揣著相機與錄音袭景,去河邊找鬼。 笑死闭树,一個胖子當(dāng)著我的面吹牛耸棒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播报辱,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼与殃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捏肢?” 一聲冷哼從身側(cè)響起奈籽,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸵赫,沒想到半個月后衣屏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡辩棒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年狼忱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片一睁。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡钻弄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出者吁,到底是詐尸還是另有隱情窘俺,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布复凳,位于F島的核電站瘤泪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏育八。R本人自食惡果不足惜对途,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望髓棋。 院中可真熱鬧实檀,春花似錦惶洲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至镣奋,卻和暖如春币呵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侨颈。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留芯义,地道東北人哈垢。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像扛拨,于是被迫代替她去往敵國和親耘分。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • JavaScript語言的執(zhí)行環(huán)境是‘單線程’的(也就是說绑警,執(zhí)行后續(xù)的代碼之前必須完成前面的任務(wù),也就是采用的是阻...
    kim_jin閱讀 575評論 0 0
  • Java異步編程實戰(zhàn) chap1 認識異步編程 異步編程概念與作用在使用同步編程方式時求泰,由于每個線程同時只能發(fā)起一...
    landon30閱讀 1,189評論 0 0
  • 同步和異步是對相北启,阻塞與非阻塞也是相對的卜朗,這個好理解,但這兩組術(shù)語之間怎么區(qū)分咕村,或者有什么聯(lián)系场钉,從字面上確實有點繞...
    傻豬俠閱讀 380評論 0 0
  • 久違的晴天,家長會懈涛。 家長大會開好到教室時逛万,離放學(xué)已經(jīng)沒多少時間了。班主任說已經(jīng)安排了三個家長分享經(jīng)驗批钠。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評論 16 22
  • 今天感恩節(jié)哎宇植,感謝一直在我身邊的親朋好友。感恩相遇价匠!感恩不離不棄当纱。 中午開了第一次的黨會,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,564評論 0 11