SHIN
Node.js 실전 팁 20선
20편Node.js는 싱글 스레드이지만 worker_threads 모듈로 진짜 OS 스레드를 사용할 수 있습니다.
// worker.js
const { parentPort, workerData } = require('worker_threads');
function heavyCompute(n) {
let result = 0;
for (let i = 0; i < n; i++) result += Math.sqrt(i);
return result;
}
parentPort.postMessage(heavyCompute(workerData.n));// main.js
const { Worker } = require('worker_threads');
function runWorker(n) {
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', { workerData: { n } });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker 비정상 종료: ${code}`));
});
});
}
async function main() {
console.time('parallel');
const results = await Promise.all([
runWorker(1e8),
runWorker(1e8),
runWorker(1e8),
runWorker(1e8),
]);
console.timeEnd('parallel');
console.log(results);
}
main();const { Worker } = require('worker_threads');
const os = require('os');
class WorkerPool {
constructor(workerFile, size = os.cpus().length) {
this.workers = [];
this.queue = [];
for (let i = 0; i < size; i++) {
this._addWorker(workerFile);
}
}
_addWorker(file) {
const worker = new Worker(file);
worker.busy = false;
worker.on('message', (result) => {
worker.busy = false;
worker._resolve(result);
this._processQueue();
});
this.workers.push(worker);
}
_processQueue() {
if (this.queue.length === 0) return;
const idle = this.workers.find((w) => !w.busy);
if (!idle) return;
const { data, resolve } = this.queue.shift();
idle.busy = true;
idle._resolve = resolve;
idle.postMessage(data);
}
run(data) {
return new Promise((resolve) => {
this.queue.push({ data, resolve });
this._processQueue();
});
}
}
const pool = new WorkerPool('./worker.js');// 메인
const shared = new SharedArrayBuffer(4);
const arr = new Int32Array(shared);
const worker = new Worker('./shared-worker.js', {
workerData: { shared }
});
worker.on('exit', () => {
console.log('결과:', arr[0]); // Worker가 직접 수정한 값
});// shared-worker.js
const { workerData } = require('worker_threads');
const arr = new Int32Array(workerData.shared);
Atomics.add(arr, 0, 42); // 원자적 연산으로 안전하게 수정| 적합 | 부적합 |
|---|---|
| 이미지/비디오 처리 | 단순 I/O 작업 |
| 암호화/해시 연산 | 짧은 계산 |
| JSON 파싱 (대용량) | 네트워크 요청 |
| 기계학습 추론 | DB 쿼리 |