理解node的單線程和異步

傳統(tǒng)多線程異步

傳統(tǒng)的異步是多線程的,當(dāng)要同時(shí)做兩件事的時(shí)候,他們是執(zhí)行在不同的線程里的。這就像是柜臺(tái)賣東西,來(lái)了一個(gè)人就得找一個(gè)員工陪他,直到這個(gè)人走了這個(gè)員工才能接待下一個(gè)客人。店內(nèi)的員工就像線程池里的空閑線程,空閑的時(shí)候可以去接待客人,可是同時(shí)只能接待一個(gè)人,要接待其他人就得找另外一個(gè)人。

電腦里的線程相當(dāng)于一個(gè)員工團(tuán)隊(duì),哪里需要去哪里。多線程的異步好處在于可以更多的占用系統(tǒng)的資源,每次開(kāi)辟線程,就像是從這個(gè)團(tuán)隊(duì)里找一個(gè)人來(lái),團(tuán)隊(duì)人總共就那么多,搶一個(gè)過(guò)來(lái)就多一點(diǎn)勞動(dòng)力,接待的客人也就更多。而這樣做的缺點(diǎn)在于創(chuàng)建和銷毀線程的開(kāi)銷是非常大的,每個(gè)線程都需要占用資源,這樣資源分配不過(guò)來(lái),柜臺(tái)沒(méi)辦法接待太多客人。并且如果有一個(gè)客人看的時(shí)間太久了就會(huì)讓一名接待人員一直不能去接待其他客人,這樣本來(lái)就吃緊的資源就更分配不過(guò)來(lái)了。

node.JS的單線程異步

如果拘泥于傳統(tǒng)的異步,肯定會(huì)發(fā)出疑問(wèn):?jiǎn)尉€程怎么能異步?

讓我們來(lái)想一個(gè)問(wèn)題,什么是異步?最直白的回答就是"讓兩個(gè)操作同時(shí)進(jìn)行"??墒窃趩尉€程里,一次只能做一件事情,怎們能有異步呢。如果是普通的操作自然是不能,可是io可以,因?yàn)閕o操作的等待時(shí)間內(nèi)是不占用任何系統(tǒng)資源的,也就是說(shuō)你盡可以放它慢慢弄,只要執(zhí)行完了通知我一聲就行了。

什么意思呢,我們拿燒水做飯的例子來(lái)講。

在同步的模式下,我們先燒水,我們就等水燒開(kāi),燒開(kāi)后再來(lái)切菜、煮飯,然后等飯煮熟后再來(lái)炒菜。

在多線程異步下,我們先燒水,這個(gè)同時(shí)我們要切菜和煮飯,那叫另一個(gè)人來(lái)切菜,切完菜后他發(fā)現(xiàn)要煮飯,可是自己接下來(lái)要炒菜,那看看剛剛燒水的人燒完了沒(méi)有,燒完了就讓他來(lái)煮飯,沒(méi)燒完再叫另一個(gè)人來(lái)煮飯,自己繼續(xù)炒菜。最后大家都做完了,這個(gè)事情就算玩了。

而單線程異步下,我們先燒水,然后放著水在那里燒,再去切菜。這時(shí)候菜切完了,先去檢查水燒好了沒(méi),如果燒好了就用這個(gè)水去做點(diǎn)事,如果沒(méi)燒好,繼續(xù)放著燒,然后煮飯也和燒水一樣,我不是放人去盯著有沒(méi)有煮好,而是做完一件事情去看這件事有沒(méi)有做好。

在node中,對(duì)于io的操作使用通知的方式,而不像傳統(tǒng)的異步操作,使用線程去監(jiān)視他。

我對(duì)node的事件輪詢的理解是這樣的,主線程分配任務(wù)下去,注冊(cè)回調(diào)函數(shù)。主線程里在執(zhí)行代碼的時(shí)候io繼續(xù)等待,主線程執(zhí)行完畢后進(jìn)行輪詢,因?yàn)檫@個(gè)時(shí)候主線程是空閑狀態(tài),所以可以一直輪詢,直到發(fā)現(xiàn)有某一個(gè)io操作給他發(fā)了信號(hào)告訴他我現(xiàn)在弄好了,你可以用這個(gè)數(shù)據(jù),主線程的資源就拿來(lái)執(zhí)行回調(diào)函數(shù)。也就是說(shuō)從始至終都只有主線程在做事情,主線程要不然是在執(zhí)行函數(shù),要不然就是在進(jìn)行事件的輪詢,去尋找有哪個(gè)事件完成了需要執(zhí)行他的回調(diào)函數(shù)。

換句話說(shuō),我們繼續(xù)用剛剛的例子,這個(gè)人不是在切菜或者炒菜,就是在檢查水有沒(méi)有燒開(kāi),飯有沒(méi)有煮熟。所以即使是單線程依舊能使用異步模式。

總結(jié)

多線程并不是異步的必須因素,這里談一下io,io操作本身并不執(zhí)行在程序中,而是交給別人去做,等他做好了我們?cè)倌玫浇Y(jié)果。我之前考慮最多的就是io難道不阻塞嗎,后來(lái)才明白io的時(shí)候線程是0消耗的,完全處于等待狀態(tài)。

所謂的單線程異步,正是合理分配了io的等待時(shí)間,讓主線程去做其他事情,在主線程空閑的時(shí)候才來(lái)檢查等待的任務(wù)有沒(méi)有完成??偟膩?lái)說(shuō),node適合io多,高并發(fā)的事,因?yàn)檫@些事情不必等待,也不必創(chuàng)建新的線程,而是分給別人去做,node只需要等待結(jié)果就好了。但它并不適合計(jì)算密集型的事情,因?yàn)楫?dāng)一個(gè)計(jì)算阻塞了主線程,就無(wú)法使下一個(gè)任務(wù)被輪詢到,后面所有的任務(wù)都會(huì)被阻塞住。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容