您好,登錄后才能下訂單哦!
今天小編給大家分享一下node的多進程和多線程是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
在node.js中,javascript代碼的執行是單線程執行的,可是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('http://localhost:4000/ start') })
上面這串代碼,如果http請求了 /compute
,node會調用cpu進行大量的計算,這時如果有其他http請求進入,將會發生阻塞。
那么如何解決這個問題呢?
有兩種方案,一種是使用children_process
或者cluster
開啟多進程進行計算,一種是使用worker_thread
開啟多線程進行計算
多進程 vs 多線程
對比一下多線程與多進程:
屬性 | 多進程 | 多線程 | 比較 |
---|---|---|---|
數據 | 數據共享復雜,需要用IPC;數據是分開的,同步簡單 | 因為共享進程數據,數據共享簡單,同步復雜 | 各有千秋 |
CPU、內存 | 占用內存多,切換復雜,CPU利用率低 | 占用內存少,切換簡單,CPU利用率高 | 多線程更好 |
銷毀、切換 | 創建銷毀、切換復雜,速度慢 | 創建銷毀、切換簡單,速度很快 | 多線程更好 |
coding | 編碼簡單、調試方便 | 編碼、調試復雜 | 編碼、調試復雜 |
可靠性 | 進程獨立運行,不會相互影響 | 線程同呼吸共命運 | 多進程更好 |
分布式 | 可用于多機多核分布式,易于擴展 | 只能用于多核分布式 | 多進程更好 |
采用多線程來解決上面代碼的計算問題:
//api.js const Koa = require('koa'); const app = new Koa(); const {Worker} = require('worker_threads') app.use(async (ctx) => { const url = ctx.request.url; if (url === '/') { ctx.body = {name: 'xxx', age: 14} } if (url === '/compute') { const sum = await new Promise(resolve => { const worker = new Worker(__dirname+'/compute.js') //接收信息 worker.on('message', data => { resolve(data) }) }) ctx.body = {sum} } }) app.listen(4000, () => { console.log('http://localhost:4000/ start') }) //computer.js const {parentPort}=require('worker_threads') let sum=0 for (let i = 0; i <1000000000 ; i++) { sum+=i } //發送信息 parentPort.postMessage(sum)
采用多進程來解決上面代碼的計算問題:
//api.js const Koa = require('koa'); const app = new Koa(); const {fork} = require('child_process') app.use(async (ctx) => { const url = ctx.request.url; if (url === '/') { ctx.body = {name: 'xxx', age: 14} } if (url === '/compute') { const sum = await new Promise(resolve => { const worker =fork(__dirname+'/compute.js') worker.on('message', data => { resolve(data) }) }) ctx.body = {sum} } }) app.listen(4000, () => { console.log('http://localhost:4000/ start') }) //computer.js let sum=0 for (let i = 0; i <1000000000 ; i++) { sum+=i } process.send(sum)
以上就是“node的多進程和多線程是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。