日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Node.js中的多線程和多進(jìn)程

Node.js 是一個免費的跨平臺 JavaScript 運行時環(huán)境,盡管它本質(zhì)上是單線程的,但是可以在后臺使用多個線程來執(zhí)行異步代碼。

公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計、成都做網(wǎng)站、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出婺源免費做網(wǎng)站回饋大家。

由于 Node.js 的非阻塞性質(zhì),不同的線程執(zhí)行不同的回調(diào),這些回調(diào)首先委托給事件循環(huán)。Node.js 運行時負(fù)責(zé)處理所有這一切。

為什么要用 NodeJS?

JavaScript 最初是作為一種單線程編程語言構(gòu)建的,僅在 Web 瀏覽器中運行。這意味著在一個過程中,只有一組指令能夠在給定的時間執(zhí)行。

僅在當(dāng)前代碼塊的執(zhí)行完成后,才移至下一個代碼塊。但是,JavaScript 的單線程性質(zhì)使實現(xiàn)變得容易。

最初 JavaScript 僅用于向網(wǎng)站添加少量交互。所以并沒有對多線程的需求。但是時代已經(jīng)變了,用戶要求也越來越高,JavaScript 已成為 Web 上流行的編程語言。

多線程現(xiàn)在變得很普遍。由于 JavaScript 是單線程語言,因此無法在其中實現(xiàn)多線程。幸運的是,在這種情況下,有一個很好的解決方法:Node.js。

Node.js 框架并不少,這要歸功于 JavaScript 運行時環(huán)境(尤其是 JavaScript)的普遍流行。在繼續(xù)本文之前,讓我們了解一些有關(guān) Node.js 的重要觀點:

  • 可以用 send 函數(shù)將消息從子進(jìn)程傳遞到其他子進(jìn)程和主進(jìn)程
  • 支持 fork 多個進(jìn)程
  • 主進(jìn)程和子進(jìn)程之間不共享狀態(tài)

為什么要 fork 進(jìn)程?

在兩種情況下,我們需要 fork 一個流程:

  • 通過將任務(wù)委派給其他進(jìn)程來提高速度
  • 用于釋放內(nèi)存和卸載單個進(jìn)程

可以將數(shù)據(jù)發(fā)送到子進(jìn)程,也可以將其送回。

Node.js 的方式

Node.js 使用兩種類型的線程:

  • 通過事件循環(huán)處理主線程,
  • 工作池中有許多輔助線程

事件循環(huán)負(fù)責(zé)獲取回調(diào)或函數(shù),并將其注冊以供將來執(zhí)行。它與正確的 JavaScript 代碼在同一線程中運行。一旦 JavaScript 操作阻塞了線程,事件循環(huán)也會被阻塞。

工作池是一個執(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 庫中實現(xiàn)的,Node.js 在 JS 和 C++ 之間進(jìn)行內(nèi)部通信時會稍有延遲。不過這幾乎是不可察覺的。

一切都很好,直到我們遇到同步執(zhí)行復(fù)雜操作的要求。任何需要大量時間執(zhí)行的函數(shù)都會導(dǎo)致主線程阻塞。

如果程序具有多個占用大量 CPU 的函數(shù),將會導(dǎo)致服務(wù)器吞吐量的顯著下降。在最壞的情況下,服務(wù)器將會失去響應(yīng),并且無法將任務(wù)委派給工作池。

諸如 AI、大數(shù)據(jù)和機器學(xué)習(xí)之類的領(lǐng)域無法從 Node.js 中受益,因為這些操作阻塞了主線程,并使服務(wù)器失去響應(yīng)。但是這隨著 Node.js v10.5.0 的到來而改變,該版本增加了對多線程的支持。

并發(fā)和 CPU 綁定任務(wù)的挑戰(zhàn)

在 JavaScript 中建立并發(fā)可能很困難。允許多個線程訪問相同的內(nèi)存會導(dǎo)致競爭狀態(tài),這不僅使故障難以重現(xiàn),而且解決起來也很困難。

Node.js 最初被實現(xiàn)為基于異步 I/O 的服務(wù)器端平臺。通過簡單地消除線程需求,這使很多事情變得容易。是的,Node.js 程序是單線程的,但不是典型的方式。

我們可以在 Node.js 中并行運行,但是不需要創(chuàng)建線程。操作系統(tǒng)和虛擬機共同并行使用 I/O,然后在需要將數(shù)據(jù)發(fā)送回 JavaScript 代碼時,JS 代碼在單個線程中運行。

除 JS 代碼外,所有內(nèi)容均在 Node.js 中并行運行。與異步塊不同,JS 的同步塊總是一次執(zhí)行一次。與代碼執(zhí)行相比,等待 JS 中產(chǎn)生 I/O 事件所話費的時間要多得多。

Node.js 程序僅調(diào)用所需的函數(shù)或回調(diào),而不會阻止其他代碼的執(zhí)行。最初 JavaScript 和 Node.js 都不打算處理 CPU 密集型或 CPU 綁定的任務(wù)。

當(dāng)代碼最少時,執(zhí)行將會是敏捷的。但是計算量越大,執(zhí)行速度就越慢。

如果你仍然嘗試在 JS 和 Node 中完成 CPU 密集型任務(wù),那么將會使瀏覽器中的 UI 凍結(jié)并對所有 I/O 事件進(jìn)行排隊處理。盡管如此,我們已經(jīng)走了很遠(yuǎn)?,F(xiàn)在有了 worker_threads 模塊。

worker_threads 模塊使多線程變得簡單

Node.js v10.5.0 于 2018 年 6 月發(fā)布,引入了 worker_threads 模塊。它有助于在流行的 JavaScript 運行時環(huán)境中實現(xiàn)并發(fā)。該模塊允許創(chuàng)建功能齊全的多線程 Node.js 應(yīng)用。

從技術(shù)上講,工作線程是在單獨的線程中產(chǎn)生的一些代碼。要開始使用輔助線程,需要先導(dǎo)入 worker_threads 模塊。之后需要創(chuàng)建 Worker 類的實例以創(chuàng)建工作線程。

創(chuàng)建 Worker 類的實例時,有兩個參數(shù):

  • 第一個參數(shù)提供擴展名 .js 或 .mjs 的文件路徑,其中包含工作程序線程的代碼,
  • 第二個參數(shù)提供了一個包含 workerData 屬性的對象,該屬性包含工作線程開始執(zhí)行時將訪問的數(shù)據(jù)

輔助線程能夠調(diào)度多個消息事件。因此,回調(diào)方法優(yōu)先于返回 promise。

工作線程之間的通信是基于事件的,即偵聽器設(shè)置為在工作線程發(fā)送事件后立即調(diào)用。最常見的 4 個事件是:

 
 
 
 
  1. worker.on('error', (error) => {});

(1) 當(dāng)工作線程中有未捕獲的異常時發(fā)出。接下來工作線程終止,并且該錯誤可以作為回調(diào)中的第一個參數(shù)使用。

 
 
 
 
  1. worker.on('exit', (exitCode) => {})

(2) 當(dāng)輔助線程退出時發(fā)出。如果在工作線程中調(diào)用了 process.exit(),則會將 exitCode 提供給回調(diào)。如果 worker.terminate() 終止工作線程,則代碼為 1。

 
 
 
 
  1. worker.on('message', (data) => {});

(3) 當(dāng)工作線程將數(shù)據(jù)發(fā)送到父線程時發(fā)出。

 
 
 
 
  1. worker.on('online', () => {});

(4) 當(dāng)工作線程停止解析 JS 代碼并開始執(zhí)行時發(fā)出。盡管不常用,但 online 事件在特定情況下可能會提供更多信息。

使用工作線程的方式

有兩種使用工作線程的方法:

  • 方法 1 – 涉及產(chǎn)生工作線程,執(zhí)行其代碼并將結(jié)果發(fā)送到父線程。此方法需要每次為新任務(wù)從頭創(chuàng)建新的 worker 線程。
  • 方法 2 – 涉及生成 worker 線程并為消息事件設(shè)置偵聽器。每次觸發(fā)該消息時,輔助線程都會執(zhí)行代碼,并將結(jié)果發(fā)送回父線程。輔助線程保持活動狀態(tài),以備將來使用。

方法 2 也被稱為工作池。這是因為該方法涉及創(chuàng)建 worker 的工作池,先讓他們等待,并在需要時去調(diào)度消息事件來執(zhí)行任務(wù)。

由于從頭創(chuàng)建工作線程需要創(chuàng)建虛擬機以及解析和執(zhí)行代碼,因此官方 Node.js 文檔 建議采用方法 2。此外,方法 2 更為實用,比方法 1 更有效。

(1) worker_threads 模塊中可用的重要屬性

  • isMainThread – 當(dāng)不在工作線程內(nèi)操作時,此屬性為 true。如果需要,則可以在 worker 文件的開頭包含一個簡單的 if 語句。這樣可以確保它僅作為工作線程運行。
  • parentPort – MessagePort 的實例,用于與父線程進(jìn)行通信。
  • threadId – 分配給工作線程的唯一標(biāo)識符。
  • workerData – 包含在 worker 線程的構(gòu)造函數(shù)中的數(shù)據(jù)。

(2) Node.js 中的多進(jìn)程

為了使 Node.js 利用多核系統(tǒng)的功能,可以用一些進(jìn)程。流行的 javascript 運行時環(huán)境中有稱被為 cluster 的模塊,該模塊提供對多進(jìn)程的支持。

使用 cluster 模塊可以產(chǎn)生多個子進(jìn)程,這些子進(jìn)程可以共享一個公共端口。當(dāng)子進(jìn)程投入使用時,使用 NodeJS 的系統(tǒng)可以處理更大的工作量。

(3) 后端的 Node.js

互聯(lián)網(wǎng)已經(jīng)成為全球數(shù)以百萬計公司的選擇平臺。因此,為使一家企業(yè)發(fā)揮最大潛力,并在此過程中脫穎而出,必須擁有強大的網(wǎng)絡(luò)形象。

這一切都始于一個強大而直觀的網(wǎng)站。要打造一個完美無瑕的網(wǎng)站,重要的是選擇最佳的前端和后端技術(shù)。盡管本質(zhì)上是單線程的,但 Node.js 是開發(fā)后端 Web 服務(wù)的選擇。

盡管有大量的后端多線程選擇,但老牌公司還是喜歡 Node.js。這是因為 Node.js 提供了在 JavaScript 中使用多線程的變通方法,而 JavaScript 已經(jīng)是“Web上最流行的編程語言”。

總結(jié)

worker_threads 模塊提供了一種在 Node.js 程序中實現(xiàn)多線程的簡便方法。通過將繁重的計算委派給工作線程,可以顯著提高服務(wù)器的吞吐量。

借助對多線程的支持,Node.js 將繼續(xù)吸引越來越多的來自 AI、大數(shù)據(jù)和機器學(xué)習(xí)等計算密集型領(lǐng)域的開發(fā)人員、工程師和其他專業(yè)人員。


網(wǎng)站欄目:Node.js中的多線程和多進(jìn)程
鏈接地址:http://www.dlmjj.cn/article/cdgohdp.html