NodeJ는 단일 스레드입니까?
Node.js는 단일 스레드에서 JavaScript 코드를 실행합니다. 즉, 코드는 한 번에 하나의 작업만 수행할 수 있습니다. 그러나 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에서 프로그램을 실행하고 있습니다. 한 번에 하나의 작업을 실행할 수 있습니다.
프로세스를 자세히 살펴 보겠습니다. 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
스레드는 애플리케이션 내에서 여러 실행 경로를 구현하는 비교적 가벼운 방법입니다. 시스템 수준에서 프로그램은 나란히 실행되며 시스템은 필요와 다른 프로그램의 필요에 따라 각 프로그램에 실행 시간을 할당합니다.
non-blocking route와 blocking route로 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대한 요청 하나만 /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)



































