NodeJs はシングルスレッドですか?
Node.js は JavaScript コードを単一スレッドで実行します。つまり、コードは一度に 1 つのタスクしか実行できません。ただし、Node.js 自体はマルチスレッドであり、ディスクからのファイルの読み取りやネットワーク リクエストなどの I/O 操作を処理する「libuv」ライブラリを通じて隠しスレッドを提供します。Node.js は、隠しスレッドを使用することにより、メイン スレッドをブロックせずにコードで I/O リクエストを実行できる非同期メソッドを提供します。
Node.js は、worker-threads モジュールを導入しました。このモジュールを使用すると、スレッドを作成し、JavaScript タスクを並行して実行できます。スレッドがタスクを完了すると、その結果をメインスレッドで使用できるように、結果を含むメッセージがメインスレッドに送信されます。ワーカースレッドはメインスレッドをブロックしないので、タスクを分割して複数のパーに分散して最適化できます。
例を作って詳しく見てみましょう。
Nodejs プロジェクトを作成し、Express フレームワークをインストールしています
mkdir multiple-thread
cd multiple-thread
npm init -y
npm install express
まず、プロセスとスレッドがあります。私たちはそれらの違いを知っておく必要があります。
プロセスとは何ですか?
プロセスはOS上でプログラムを実行しています。一度に 1 つのタスクを実行できます。
プロセスを詳しく見てみましょう。JS ファイルを作成し、プロセスをログに記録します。
//ex-process.js
const processName = process.argv.slice(2)[0]
let count = 0;
while(true){
count++;
if(count === 3333 || count=== 6666){
console.log(`${processName}: ${count}`)
}
}
node ex-process.js FirstEx &
// & symbol means the Node program to run in the background, so we can use
our teminal for other works
Output
[1] 82942
FirstEx: 3333
FirstEx: 6666
ps |grep node
Output
82942 ttys001 2:38.85 node ex-process.js FirstEx
83105 ttys001 0:00.00 grep node
スレッドは、アプリケーション内で複数の実行パスを実装する比較的軽量な方法です。システム レベルでは、プログラムは並行して実行され、システムはそのプログラムのニーズと他のプログラムのニーズに基づいて各プログラムに実行時間を配分します。
ノンブロッキングルートとブロッキングルートを使ってExpress Serverをコーディングしてみましょう
ユーザー向けの通常のブロック ルートをコーディングしてみましょう。でapp.js;
const express = require('express');
const app = express();
app.get('/hello', (req,res)=>{
res.status(200).send(`Hello`);
})
app.get('/blocking-route', (req,res)=>{
console.log('Blocking route called')
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
})
app.listen(7333, ()=> console.log('Server started on port 7333'));
blocking-routeが完了して応答が返されるまで応答しません。
なぜ即座に応答しなかったのでしょうか?
この例では、CPU バウンドの for ループがメインスレッドをブロックします。メインスレッドがブロックされている間、Node.js は CPU バウンドのプロセスが終了するまでクエリを処理できません。したがって、他のルートはどれもルートロード/helloとして機能しません/blocking-route。
GETしたがって、のような非ブロッキング ルートへの同時リクエストが数千件ある API がある場合/hello、 への 1 つのリクエストだけで/blocking-routeAPI 内のすべてのルートがブロックされます。つまり、すべてのアプリケーション ルートが応答しなくなります。
DAAA IT の JavaScript、別のスレッドは使用できません
Dudeeee JSだけではありません。ノデイスです。ワーカースレッドを使用して、CPU に依存するタスクをオフロードできます。
nprocまず最初に、コマンドでコアをチェックする必要があります。
nproc
output
8
のような別の JS ファイルを作成しましょうworker.js。名前は自由です。このファイルでは、CPU を集中的に使用するタスクを実行します
//worker.js
const { parentPort } = require("worker_threads");
let counter = 0;
console.log("Worker started");
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
parentPort.postMessage(counter);
//app.js
const express = require("express");
const { Worker } = require("worker_threads");
const app = express();
app.get("/blocking-route", async (req, res) => {
console.log("Blocking route called");
let counter = 0;
for (let i = 0; i < 15_000_000_000; i++) {
counter++;
}
res.status(200).send(`result is ${counter}`);
});
app.get("/hello", (req, res) => {
res.status(200).send(`Hello`);
});
app.get("/non-blocking-route", async (req, res) => {
console.log("Non-blocking route called");
const worker = new Worker("./worker.js");
worker.on("message", (data) => {
res.status(200).send(`result is ${data}`);
});
worker.on("error", (err) => {
res.status(404).send(` error ${err}`);
});
console.log("I am not blocked");
});
app.listen(7333, () => console.log("Server started on port 7333"));
でサーバーを起動しましょうnode app.js。ブラウザを開いて、http://localhost:7333/non-blocking-route応答が返される前に に進みますhttp://localhost:7333/hello。気づきましたか?すぐに返答が得られます。ブロックはありません。他のルートの読み込みが完了するのを待ちませんでした。CPU に依存するタスクがオフロードされて別のスレッドが動作し、メインスレッドがすべてのリクエストを処理するためです。より多くのワーカーを使用してパフォーマンスを向上させることができます。たとえば、8 つのコアがあり、プロセスを 8 つに分割できます。
結論
ワーカー (スレッド) は、CPU に負荷がかかる JavaScript 操作を支援します。child_processや とは異なりcluster、worker_threadsメモリを共有できます。
この記事では、worker_threads の仕組みをわかりやすく説明してみました。
読んでくれてありがとう

![とにかく、リンクリストとは何ですか?[パート1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































