這篇文章給大家分享的是有關(guān)Node.js中多線程和多進(jìn)程的案例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。
成都創(chuàng)新互聯(lián)公司專注于金鳳企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。金鳳網(wǎng)站建設(shè)公司,為金鳳等地區(qū)提供建站服務(wù)。全流程按需開(kāi)發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)Node.js 是一個(gè)免費(fèi)的跨平臺(tái) JavaScript 運(yùn)行時(shí)環(huán)境,盡管它本質(zhì)上是單線程的,但是可以在后臺(tái)使用多個(gè)線程來(lái)執(zhí)行異步代碼。
由于 Node.js 的非阻塞性質(zhì),不同的線程執(zhí)行不同的回調(diào),這些回調(diào)首先委托給事件循環(huán)。 Node.js 運(yùn)行時(shí)負(fù)責(zé)處理所有這一切?!疽曨l教程推薦:node js教程 】
JavaScript 最初是作為一種單線程編程語(yǔ)言構(gòu)建的,僅在 Web 瀏覽器中運(yùn)行。這意味著在一個(gè)過(guò)程中,只有一組指令能夠在給定的時(shí)間執(zhí)行。
僅在當(dāng)前代碼塊的執(zhí)行完成后,才移至下一個(gè)代碼塊。但是,JavaScript 的單線程性質(zhì)使實(shí)現(xiàn)變得容易。
最初,JavaScript 對(duì)于僅用于向網(wǎng)站添加少量交互。所以并沒(méi)有對(duì)多線程的需求。但是時(shí)代已經(jīng)變了,用戶要求也越來(lái)越高,JavaScript 已成為“Web 上流行的編程語(yǔ)言”。
多線程現(xiàn)在變得很普遍。由于 JavaScript 是單線程語(yǔ)言,因此無(wú)法在其中實(shí)現(xiàn)多線程。幸運(yùn)的是,在這種情況下,有一個(gè)很好的解決方法:Node.js。
Node.js 框架并不少,這要?dú)w功于 JavaScript 運(yùn)行時(shí)環(huán)境(尤其是 JavaScript)的普遍流行。在繼續(xù)本文之前,讓我們了解一些有關(guān) Node.js 的重要觀點(diǎn):
在兩種情況下,我們需要 fork 一個(gè)流程:
可以將數(shù)據(jù)發(fā)送到子進(jìn)程,也可以將其送回。
Node.js 使用兩種類型的線程:
事件循環(huán)負(fù)責(zé)獲取回調(diào)或函數(shù),并將其注冊(cè)以供將來(lái)執(zhí)行。它與正確的 JavaScript 代碼在同一線程中運(yùn)行。一旦 JavaScript 操作阻塞了線程,事件循環(huán)也會(huì)被阻塞。
工作池是一個(gè)執(zhí)行模型,負(fù)責(zé)產(chǎn)生和處理不同的線程。它同步執(zhí)行任務(wù),然后將結(jié)果返回到事件循環(huán),最后事件循環(huán)將結(jié)果提供給回調(diào)。
總而言之,工作池負(fù)責(zé)異步 I/O 操作,即與系統(tǒng)磁盤和網(wǎng)絡(luò)的交互。像 fs 和 crypto 這樣的模塊是使用工作池的主要模塊。
由于工作池是在 libuv 庫(kù)中實(shí)現(xiàn)的,Node.js 在 JS 和 C++ 之間進(jìn)行內(nèi)部通信時(shí)會(huì)稍有延遲。不過(guò)這幾乎是不可察覺(jué)的。
一切都很好,直到我們遇到同步執(zhí)行復(fù)雜操作的要求。任何需要大量時(shí)間執(zhí)行的函數(shù)都會(huì)導(dǎo)致主線程阻塞。
如果程序具有多個(gè)占用大量 CPU 的函數(shù),將會(huì)導(dǎo)致服務(wù)器吞吐量的顯著下降。在最壞的情況下,服務(wù)器將會(huì)失去響應(yīng),并且無(wú)法將任務(wù)委派給工作池。
諸如 AI、大數(shù)據(jù)和機(jī)器學(xué)習(xí)之類的領(lǐng)域無(wú)法從 Node.js 中受益,因?yàn)檫@些操作阻塞了主線程,并使服務(wù)器失去響應(yīng)。但是這隨著 Node.js v10.5.0 的到來(lái)而改變,該版本增加了對(duì)多線程的支持。
在 JavaScript 中建立并發(fā)可能很困難。允許多個(gè)線程訪問(wèn)相同的內(nèi)存會(huì)導(dǎo)致競(jìng)爭(zhēng)狀態(tài),這不僅使故障難以重現(xiàn),而且解決起來(lái)也很困難。
Node.js 最初被實(shí)現(xiàn)為基于異步 I/O 的服務(wù)器端平臺(tái)。通過(guò)簡(jiǎn)單地消除線程需求,這使很多事情變得容易。是的,Node.js 程序是單線程的,但不是典型的方式。
我們可以在 Node.js 中并行運(yùn)行,但是不需要?jiǎng)?chuàng)建線程。操作系統(tǒng)和虛擬機(jī)共同并行使用 I/O,然后在需要將數(shù)據(jù)發(fā)送回 JavaScript 代碼時(shí),JS 代碼在單個(gè)線程中運(yùn)行。
除 JS 代碼外,所有內(nèi)容均在 Node.js 中并行運(yùn)行。與異步塊不同,JS 的同步塊總是一次執(zhí)行一次。與代碼執(zhí)行相比,等待 JS 中產(chǎn)生 I/O 事件所話費(fèi)的時(shí)間要多得多。
Node.js 程序僅調(diào)用所需的函數(shù)或回調(diào),而不會(huì)阻止其他代碼的執(zhí)行。最初 JavaScript 和 Node.js 都不打算處理 CPU 密集型或 CPU 綁定的任務(wù)。
當(dāng)代碼最少時(shí),執(zhí)行將會(huì)是敏捷的。但是計(jì)算量越大,執(zhí)行速度就越慢。
如果你仍然嘗試在 JS 和 Node 中完成 CPU 密集型任務(wù),那么將會(huì)使瀏覽器中的 UI 凍結(jié)并對(duì)所有 I/O 事件進(jìn)行排隊(duì)處理。盡管如此,我們已經(jīng)走了很遠(yuǎn)?,F(xiàn)在有了 worker_threads 模塊。
Node.js v10.5.0 于 2018 年 6 月發(fā)布,引入了 worker_threads 模塊。它有助于在流行的 JavaScript 運(yùn)行時(shí)環(huán)境中實(shí)現(xiàn)并發(fā)。該模塊允許創(chuàng)建功能齊全的多線程 Node.js 應(yīng)用。
從技術(shù)上講,工作線程是在單獨(dú)的線程中產(chǎn)生的一些代碼。要開(kāi)始使用輔助線程,需要先導(dǎo)入 worker_threads 模塊。之后需要?jiǎng)?chuàng)建 Worker 類的實(shí)例以創(chuàng)建工作線程。
創(chuàng)建 Worker 類的實(shí)例時(shí),有兩個(gè)參數(shù):
輔助線程能夠調(diào)度多個(gè)消息事件。因此,回調(diào)方法優(yōu)先于返回 promise。
工作線程之間的通信是基于事件的,即偵聽(tīng)器設(shè)置為在工作線程發(fā)送事件后立即調(diào)用。最常見(jiàn)的 4 個(gè)事件是:
worker.on('error', (error) => {});
worker.on('exit', (exitCode) => {})
process.exit()
,則會(huì)將 exitCode 提供給回調(diào)。如果 worker.terminate()
終止工作線程,則代碼為 1。worker.on('message', (data) => {});
worker.on('online', () => {});
有兩種使用工作線程的方法:
方法 2 也被稱為工作池。這是因?yàn)樵摲椒ㄉ婕皠?chuàng)建 worker 的工作池,先讓他們等待,并在需要時(shí)去調(diào)度消息事件來(lái)執(zhí)行任務(wù)。
由于從頭創(chuàng)建工作線程需要?jiǎng)?chuàng)建虛擬機(jī)以及解析和執(zhí)行代碼,因此官方 Node.js 文檔 建議采用方法 2。此外,方法 2 更為實(shí)用,比方法 1 更有效。
為了使 Node.js 利用多核系統(tǒng)的功能,可以用一些進(jìn)程。流行的 javascript 運(yùn)行時(shí)環(huán)境中有稱被為 cluster 的模塊,該模塊提供對(duì)多進(jìn)程的支持。
使用 cluster 模塊可以產(chǎn)生多個(gè)子進(jìn)程,這些子進(jìn)程可以共享一個(gè)公共端口。當(dāng)子進(jìn)程投入使用時(shí),使用 NodeJS 的系統(tǒng)可以處理更大的工作量。
互聯(lián)網(wǎng)已經(jīng)成為全球數(shù)以百萬(wàn)計(jì)公司的選平臺(tái)。因此,為使一家企業(yè)發(fā)揮大潛力,并在此過(guò)程中脫穎而出,必須擁有強(qiáng)大的網(wǎng)絡(luò)形象。
這一切都始于一個(gè)強(qiáng)大而直觀的網(wǎng)站。要打造一個(gè)完美無(wú)瑕的網(wǎng)站,重要的是選擇最佳的前端和后端技術(shù)。盡管本質(zhì)上是單線程的,但 Node.js 是開(kāi)發(fā)后端 Web 服務(wù)的選。
盡管有大量的后端多線程選擇,但知名公司還是喜歡 Node.js。這是因?yàn)?Node.js 提供了在 JavaScript 中使用多線程的變通方法,而 JavaScript 已經(jīng)是“Web上最流行的編程語(yǔ)言”。
worker_threads 模塊提供了一種在 Node.js 程序中實(shí)現(xiàn)多線程的簡(jiǎn)便方法。通過(guò)將繁重的計(jì)算委派給工作線程,可以顯著提高服務(wù)器的吞吐量。
借助對(duì)多線程的支持,Node.js 將繼續(xù)吸引越來(lái)越多的來(lái)自 AI、大數(shù)據(jù)和機(jī)器學(xué)習(xí)等計(jì)算密集型領(lǐng)域的開(kāi)發(fā)人員、工程師和其他專業(yè)人員。
感謝各位的閱讀!關(guān)于Node.js中多線程和多進(jìn)程的案例分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!