首頁  >  文章  >  web前端  >  一文聊聊node的多進程和多線程

一文聊聊node的多進程和多線程

青灯夜游
青灯夜游轉載
2022-02-28 19:47:383854瀏覽

這篇文章帶大家了解一下node.js,介紹一下node中的多進程和多線程,對比一下多進程和多線程,希望對大家有幫助!

一文聊聊node的多進程和多線程

node.js中的多進程與多執行緒

#在node.js中,javascript程式碼的執行是單執行緒執行的,可是Node 本身其實是多執行緒的。

一文聊聊node的多進程和多線程

node本身又分為三層

第一層,Node .js 標準函式庫,這部分是由Javascript寫的,也就是我們使用過程中直接能呼叫的API,在原始碼中的lib 目錄下可以看到。

第二層,Node bindings,這一層是Javascript 與底層C/C 能夠溝通的關鍵,前者透過bindings 呼叫後者,相互交換數據,是第一層和第三層的橋樑。

第三層,是支撐 Node.js 運行的關鍵,由 C/C 實現,是node實現的一些底層邏輯。

其中,第三層的Libuv,為 Node.js 提供了跨平台,線程池,事件池,非同步 I/O 等能力,是 Node.js 如此強大的關鍵。

由於Libuv提供了事件循環機制,所以在io處理方面,javascript並不會發生阻塞,所以我們用node搭建web服務時,並不需要擔心io量過大,導致其他請求阻塞。

可是,非io任務的執行,是在node主執行緒中執行的,是單執行緒執行任務,如果有非常消耗時間的同步運算任務,將會阻塞其他程式碼的執行。

const Koa = require('koa');
const app = new Koa();

app.use(async (ctx) => {
    const url = ctx.request.url;
    if (url === '/') {
        ctx.body = {name: 'xxx', age: 14}
    }
    if(url==='/compute'){
        let sum=0
        for (let i = 0; i <100000000000 ; i++) {
        sum+=i    
        }
        ctx.body={sum}
    }
})
app.listen(4000, () => {
    console.log(&#39;http://localhost:4000/ start&#39;)
})

上面這串程式碼,如果http請求了/compute ,node會呼叫cpu進行大量的計算,這時如果有其他http請求進入,將會發生阻塞。

那麼要如何解決這個問題呢?

有兩種方案,一種是使用children_processcluster開啟多進程進行計算,另一種是使用worker_thread#開啟多執行緒進行運算

多行程vs 多執行緒

#對比多執行緒與多行程:

##數據數據共享複雜,需要用IPC;數據是分開的,同步簡單因為共享進程數據,數據共享簡單,同步複雜各有千秋CPU、記憶體佔用記憶體多,切換複雜,CPU利用率低佔用記憶體少,切換簡單,CPU利用率高多執行緒更好銷毀、切換#建立銷毀、切換複雜,速度慢建立銷毀、切換簡單,速度很快多執行緒更好coding編碼簡單、調試方便編碼、調試複雜可靠性分佈式採用多線程來解決上面程式碼的計算問題:
屬性 多重行程 多執行緒 比較
##編碼、調試複雜
進程獨立運行,不會相互影響 線程同呼吸共命運 多進程更好
可用於多機多核心分佈式,易於擴充 只能用於多核心分佈式 #多進程更好
//api.js
const Koa = require(&#39;koa&#39;);
const app = new Koa();

const {Worker} = require(&#39;worker_threads&#39;)
app.use(async (ctx) => {
    const url = ctx.request.url;
    if (url === &#39;/&#39;) {
        ctx.body = {name: &#39;xxx&#39;, age: 14}
    }

    if (url === &#39;/compute&#39;) {
        const sum = await new Promise(resolve => {
            const worker = new Worker(__dirname+&#39;/compute.js&#39;)
          //接收信息
            worker.on(&#39;message&#39;, data => {
                resolve(data)
            })
        })
        ctx.body = {sum}

    }
})
app.listen(4000, () => {
    console.log(&#39;http://localhost:4000/ start&#39;)
})



//computer.js
const {parentPort}=require(&#39;worker_threads&#39;)
let sum=0
for (let i = 0; i <1000000000 ; i++) {
    sum+=i
}
//发送信息
parentPort.postMessage(sum)

這裡是官方文檔,
worker_threads

https://nodejs.org/dist/latest-v16.x/docs/api/worker_threads.html

採用多進程來解決上面程式碼的計算問題:
//api.js
const Koa = require(&#39;koa&#39;);
const app = new Koa();
const {fork} = require(&#39;child_process&#39;)

app.use(async (ctx) => {
    const url = ctx.request.url;
    if (url === &#39;/&#39;) {
        ctx.body = {name: &#39;xxx&#39;, age: 14}
    }

    if (url === &#39;/compute&#39;) {
        const sum = await new Promise(resolve => {
          const worker =fork(__dirname+&#39;/compute.js&#39;)
            worker.on(&#39;message&#39;, data => {
                resolve(data)
            })
        })
        ctx.body = {sum}

    }
})
app.listen(4000, () => {
    console.log(&#39;http://localhost:4000/ start&#39;)
})

//computer.js
let sum=0
for (let i = 0; i <1000000000 ; i++) {
    sum+=i
}
process.send(sum)

這裡是官方文檔,
child_process

https://nodejs.org/dist/latest-v16.x/docs/api/child_process .html

更多node相關知識,請造訪:
nodejs 教學

以上是一文聊聊node的多進程和多線程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除