真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Node.js是單線程的程序嗎

這篇文章主要講解了“Node.js是單線程的程序嗎”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Node.js是單線程的程序嗎”吧!

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

Node.js是單線程的程序嗎

Node.js 是單線程的程序*

所有我們自己寫的 Javsacript,V8, event loop都跑在同一個線程里面,也就是 main thrad。

哎嗨,這不正說明 node 是單線程的嗎?

但是也許你不知道 node 有很多模塊背后都是 C++ code。

雖然 node 沒有給使用者暴露控制 thread 的權(quán)限,但是 C++ 是可以使用多線程的。

那么什么時候 node 會使用多線程呢?

  • 如果一個 node 方法,背后調(diào)用C++的同步方法,那么都是跑在 main thread 里面的。

  • 如果一個 node 方法,背后調(diào)用C++的異步方法,有時候不是跑在 main thread 里面的。

Talk is cheap, show me the code.

同步方法,跑在 main thread 里面

這里 crypto 相關(guān)模塊,很多是 C++ 寫的。下面一段程序是計算hash的函數(shù),一般用來存儲密碼。

import { pbkdf2Sync } from "crypto";
const startTime = Date.now();
let index = 0;
for (index = 0; index < 3; index++) {
    pbkdf2Sync("secret", "salt", 100000, 64, "sha512");
    const endTime = Date.now();
    console.log(`${index} time, ${endTime - startTime}`);
}
const endTime = Date.now();
console.log(`in the end`);

輸出的時間,

0 time, 44 
1 time, 90
2 time, 134
in the end

可以看到每次大概都是花費~45ms,代碼 main thread 上順序執(zhí)行。

注意最后的輸出是誰? 注意這里一次 hash 在我的 cpu 需要~45ms。

異步 pbkdf2 方法,不跑在 main thread 里面

import { cpus } from "os";
import { pbkdf2 } from "crypto";
console.log(cpus().length);
let startTime = console.time("time-main-end");
for (let index = 0; index < 4; index++) {
    startTime = console.time(`time-${index}`);
    pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => {
        if (err) throw err;
        console.timeEnd(`time-${index}`);
    });
}
console.timeEnd("time-main-end");

輸出的時間,

time-main-end: 0.31ms
time-2: 45.646ms
time-0: 46.055ms
time-3: 46.846ms
time-1: 47.159ms

這里看到,main thread 早早結(jié)束,然而每次計算的時間都是45ms,要知道一個 cpu 計算 hash 的時間是45ms,這里 node 絕對使用了多個線程進行hash計算。

如果我這里把調(diào)用次數(shù)改成10次,那么時間如下,可以看到隨著CPU核數(shù)的用完,時間也在增加。再一次證明node 絕對使用了多個線程進行hash計算。

time-main-end: 0.451ms
time-1: 44.977ms
time-2: 46.069ms
time-3: 50.033ms
time-0: 51.381ms
time-5: 96.429ms // 注意這里,從第五次時間開始增加了
time-7: 101.61ms
time-4: 113.535ms
time-6: 121.429ms
time-9: 151.035ms
time-8: 152.585ms

雖然這里證明了,node絕對啟用了多線程。但是有一點點小小的問題?我的電腦的CPU是AMD R5-5600U,有6個核心12線程啊。但是為什么時間是從第五次開始增加的呢,node沒有完全利用我的CPU?。?/p>

原因是什么呢?

Node 使用了預定義的線程池,這個線程池的大小默認是4.

export UV_THREADPOOL_SIZE=6

讓我們在看一個例子,

HTTP request

import { request } from "https";
const options = {
  hostname: "www.baidu.com",
  port: 443,
  path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png",
  method: "GET",
};

let startTime = console.time(`main`);

for (let index = 0; index < 15; index++) {
  startTime = console.time(`time-${index}`);
  const req = request(options, (res) => {
    console.log(`statusCode: ${res.statusCode}`);
    console.timeEnd(`time-${index}`);
    res.on("data", (d) => {
      // process.stdout.write(d);
    });
  });

  req.on("error", (error) => {
    console.error(error);
  });

  req.end();
}

console.timeEnd("main");
main: 13.927ms
time-2: 83.247ms
time-4: 89.641ms
time-3: 91.497ms
time-12: 91.661ms
time-5: 94.677ms
.....
time-8: 134.026ms
time-1: 143.906ms
time-13: 140.914ms
time-10: 144.088ms

這里主程序也早早結(jié)束了,這里我啟動 http request 去下載15次圖片,他們花費的時間并沒有成倍增加,似乎不受限于線程池/cpu的影響。

為什么????Node 到底有沒有在使用線程池?。?/p>

如果 Node 背后的 C++ 的異步方法,首先會嘗試是否有內(nèi)核異步支持,比如這里網(wǎng)絡(luò)請是使用 epoll (Linux),如果內(nèi)核沒有提供異步方式,Node才會使用自己的線程池。。

所以 http 請求雖然是異步,不過是由內(nèi)核實現(xiàn)的,等到內(nèi)核完成后,會通知C++, C++會通知給 main thread 處理callback。

那么 Node 哪些異步方法會使用線程池呢?哪些不會呢?

  • 原生 Kernal Async

    • TCP/UDP server client

    • Unix Domain Sockets (IPC)

    • pipes

    • DNS.resolveXXX

    • tty input(stdin etc)

    • Unix signals

    • Child process

  • Thread pool

    • fs.*

    • dns.lookup

    • pipe (edge case)

這也是大部分 Node 優(yōu)化的切入點。

但是這些怎么和最重要的 Event Loop 結(jié)合起來呢?

Event Loop

相信大家都對 Event loop 非常熟悉了。Event loop 好比一個分發(fā)員,

  • 如果是遇到普通 javascript 程序或者是 callback,交給 V8 處理。

  • 如果遇到同步方法后背是 C++ 寫的,交給C++,跑在 main thread。

  • 如果遇到異步方法后背是 C++ 寫的,如果有內(nèi)核異步支持,從main thread 交給內(nèi)核處理。

  • 如果是異步方法后背是 C++ 寫的,如果沒有內(nèi)核異步支持,從 main thread 交給 thread pool。

  • thread pool 和內(nèi)核有結(jié)果都會把結(jié)果返回 event loop,如果注冊的有 javascript callback,就交給V8進行處理。

然后如此循環(huán),直到?jīng)]有東西可以處理。

所以 Node 不完全是單線程程序。

感謝各位的閱讀,以上就是“Node.js是單線程的程序嗎”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Node.js是單線程的程序嗎這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


當前文章:Node.js是單線程的程序嗎
網(wǎng)頁URL:http://weahome.cn/article/pjpgpo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部