node js 進階-node的多核實現
阿新 • • 發佈:2019-01-31
從node 出現到現在,一直被我們熟知的是它的單執行緒模型,所有的任務都在一個執行緒中完成,從而免去了頻繁切換執行緒的開銷,以及減少資源互搶的問題。但是當我們的程式是CPU 密集型模型的時候node js 就顯得不再有那麼多優勢,儘管node js 擁有非同步機制,可以把一些耗時演算法等待下個事件再實現,但是node js畢竟使用的是單執行緒模型,所以終究會出現阻塞,那node js 是如何處理高併發的呢?不會是不支援多執行緒吧?
而且雖然node js 是單執行緒非同步非阻塞的,那是不是我們就可以高枕無憂了?舉個栗子,當我們買完套餐(未領取)接著去買飲料的時候,已經叫我的號讓我去取餐,但是我等了好久才拿到飲料,所以最終我會在套餐號被叫了很久之後我才去拿套餐,這就是我們特別擔心的單執行緒的阻塞情況。
先來看一個示例程式碼:
上述程式執行出的結果:<span style="font-family:KaiTi_GB2312;font-size:18px;">var start = Date.now();//獲取當前時間戳 setTimeout(function () { console.log(Date.now() - start); for (var i = 0; i < 1000000000; i++){//執行長迴圈 } }, 1000); setTimeout(function () { console.log(Date.now() - start); }, 2000);</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;">1000
3738</span>
對於我們期望2秒之後執行的setTimeOut函式其實是經過了3738 毫秒之後才執行,因為執行了一個時間很長的for迴圈,所以我們整個node js 主執行緒被阻塞了,如果我們處理1000個使用者請求,那麼,因為其中第一個被阻塞,其餘的999個請求都會被延遲執行,這樣使用者的體驗度相當值得深思啊;雖然node 可以處理併發,但是我們依舊無法確保某一時刻不阻塞請求;
在Java,C#中都有對應的多執行緒程式設計,雖然有時候用起來會麻煩一些,但是在處理高併發的能力不得不感嘆。所以如果node js 有建立子執行緒的能力,我們使用node 處理高併發請求的問題不就迎刃而解了?
cluster可以用來讓node js 充分發揮多核CPU的效能:
<span style="font-family:KaiTi_GB2312;font-size:18px;">varcluster=require('cluster');
varnumCPUs=8;
functionfibo(n){
returnn>1?fibo(n-1)+fibo(n-2):1;
}
console.time('8cluster');
if(cluster.isMaster){
//Forkworkers.
for(vari=0;i<numCPUs;i++){
cluster.fork();
}
vari=8;
cluster.on('exit',function(worker,code,signal){
if(!--i){
console.timeEnd('8cluster');
process.exit(0);
}
});
}else{
console.log(fibo(40));
process.exit(0);
}</span>
node js 的單執行緒給我們帶來了莫大的遍歷和樂趣,但使用單執行緒的過程中要警惕node 中異常捕獲的疏忽導致整個node js 程式的崩潰,所以在使用過程中一定要小心的處理大量的迴圈,字串拼接和浮點運算。可以適當地將部分操作分給子執行緒或者子程序來完成,但是要切記子執行緒和子程序的使用也是有開銷的,要恰恰當使用;