nodejs 如何處理密集型運算
nodejs 如何處理密集型運算?
Nodejs密集型CPU解決方案
先說一下nodejs單執行緒的優勢:
推薦:《javascript高級教程》
高效能,與php相比,避免了頻繁創建切換線程的開銷,執行更加迅速,資源佔用小。
線程安全,不用擔心同一變數被多執行緒讀寫,造成程式崩潰。
單執行緒的非同步與非阻塞,其實nodejs底層存取I/O還是多執行緒的,阻塞/非阻塞與非同步/同步是兩個不同的概念,同步不代表阻塞,但是阻塞肯定就是同步;有點繞口,請聽我舉例,我去食堂打飯,我選擇了A套餐,然後工作人員幫我去配餐,如果我就站在旁邊,等待工作人員給我配餐,這種情況就稱之為同步;若工作人員幫我配餐的同時,排在我後面的人就開始點餐,這樣整個食堂的點餐服務並沒有因為我在等待A套餐而停止,這種情況就稱之為非阻塞。這個例子就簡單說明了同步但非阻塞的情況。再如果我在等待配餐的時候去買飲料,等聽到叫號再回去拿套餐,此時我的飲料也已經買好,這樣我在等待配餐的同時還執行了買飲料的任務,叫號就等於執行了回調,就是異步非阻塞了。如果我在買飲料的時候,已經叫我的號讓我去拿套餐,可是我等了好久才拿到飲料,所以我可能在大廳叫我的餐號之後很久才拿到A套餐,這也就是單線程的阻塞情況。
多執行緒:
執行緒是cpu調度的一個基本單位,一個cpu只能執行一個執行緒任務。
nodejs也可以執行多行程任務,例如引用TAGG/TAGG2模組,但不論是tagg/tagg2都是利用pthread庫和V8::Isolate類別來實作js多執行緒功能的,根據規則我們在在執行緒裡執行的函數無法使用nodejs的核心api,例如fs,crypto模組,所以還是有很大的限制。
多進程:
在支援html5的瀏覽器裡,我們可以使用webworker來將一些耗時的計算丟入worker進程中執行,這樣主進程就不會阻塞,用戶也不會有卡頓的感覺。
這裡我們需要利用nodejs的child_process模組,child_process提供了fork方法,可以啟動一個nodejs文件,將它視為worker進程,worker 工作完畢後,會把結果send給主進程,然後worker自動退出,這樣我們就利用了多進程解決了主執行緒阻塞的問題。
var express = require('express'); var fork = require('child_process').fork; var app = express(); app.get('/', function(req, res){ var worker = fork('./work.js') //创建一个工作进程 worker.on('message', function(m) {//接收工作进程计算结果 if('object' === typeof m && m.type === 'fibo'){ worker.kill();//发送杀死进程的信号 res.send(m.result.toString());//将结果返回客户端 } }); worker.send({type:'fibo',num:~~req.query.n || 1}); //发送给工作进程计算fibo的数量 }); app.listen(7878);
我們透過express監聽7878端口,對每個用戶的請求都會去fork一個子進程,透過調用worker.send方法將參數n傳遞給子進程,同時監聽子進程發送訊息的message事件,將結果回應給客戶端。
下面是被fork的work.js檔案內容:
var fibo = function fibo (n) {//定义算法 return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1; } process.on('message', function(m) { //接收主进程发送过来的消息 if(typeof m === 'object' && m.type === 'fibo'){ var num = fibo(~~m.num); //计算jibo process.send({type: 'fibo',result:num}) //计算完毕返回结果 } }); process.on('SIGHUP', function() { process.exit();//收到kill信息,进程退出 });
我們先定義函數fibo用來計算斐波那契數組,然後監聽了主執行緒發來的訊息,計算完畢之後將結果send到主線程。同時也監聽process的SIGHUP事件,觸發此事件就進程退出。
這裡我們有一點要注意,主執行緒的kill方法並不是真的使子程序退出,而是會觸發子程序的SIGHUP事件,真正的退出還是依賴process.exit()。
總結:
使用child_process模組的fork方法確實可以讓我們很好的解決單線程對cpu密集型任務的阻塞問題,同時又沒有tagg套件那樣無法使用Node.js核心api的限制。
單執行緒異步的Node.js不代表不會阻塞,在主執行緒做過多的任務可能會導致主執行緒的卡死,影響整個程式的效能,所以我們要非常小心的處理大量的循環,字串拼接和浮點運算等cpu密集型任務,合理的利用各種技術把任務丟給子執行緒或子程序去完成,保持Node.js主執行緒的暢通。
執行緒/進程的使用並不是沒有開銷的,盡可能減少創建和銷毀執行緒/進程的次數,可以提升我們系統整體的效能和出錯的機率。
以上是nodejs 如何處理密集型運算的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Node.js 是一種伺服器端 JavaScript 執行時,而 Vue.js 是一個客戶端 JavaScript 框架,用於建立互動式使用者介面。 Node.js 用於伺服器端開發,如後端服務 API 開發和資料處理,而 Vue.js 用於用戶端開發,如單一頁面應用程式和響應式使用者介面。

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

Node.js 和 Java 在 Web 開發中各有優劣,因此選擇取決於專案需求。 Node.js 擅長即時應用程式、快速開發和微服務架構,而 Java 則在企業級支援、效能和安全性方面佔優。
