[nodejs] 병렬 프로그래밍

Node.js는 비동기 프로그래밍 모델을 채택하여 I/O 작업을 효율적으로 처리합니다. 그러나 CPU 밀도가 높은 작업에 있어서는 싱글 스레드 모델이 성능 이슈를 일으킬 수 있습니다. 이러한 상황에서 병렬 프로그래밍이 유용하게 활용될 수 있습니다.

클러스터링

Node.js는 클러스터링을 통해 다수의 프로세스를 생성하여 병렬로 작업을 수행할 수 있습니다. cluster 모듈은 이를 지원하는데, 간단한 예제를 통해 살펴보겠습니다.

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`마스터 프로세스 ${process.pid}이 시작되었습니다.`);

  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`워커 프로세스 ${worker.process.pid}가 종료되었습니다.`);
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('안녕, 세계\n');
  }).listen(8000);

  console.log(`워커 프로세스 ${process.pid}이 시작되었습니다.`);
}

이 예제에서는 cluster 모듈을 사용하여 다수의 프로세스를 생성하여 HTTP 요청에 병렬로 응답할 수 있습니다. 각 프로세스는 CPU 코어에 매핑되어 독립적으로 작업을 수행합니다.

워커 스레드

Node.js 10.5.0 버전부터는 worker_threads 모듈이 도입되어 별도의 워커 스레드를 생성할 수 있습니다. 이를 통해 CPU 밀도가 높은 작업을 병렬로 처리할 수 있습니다. 다음은 간단한 예제 코드입니다.

const { Worker, isMainThread, parentPort } = require('worker_threads');

if (isMainThread) {
  const worker = new Worker(__filename);
  worker.on('message', (msg) => {
    console.log('부모 스레드가 메시지를 수신했습니다:', msg);
  });
  worker.postMessage('Hello, worker');
} else {
  parentPort.on('message', (msg) => {
    console.log('워커 스레드가 메시지를 수신했습니다:', msg);
    parentPort.postMessage('Hello, parent');
  });
}

이 예제에서는 부모 스레드와 워커 스레드 간의 통신을 통해 작업을 병렬로 수행하고 있습니다. 이를 통해 병렬 프로그래밍을 보다 효율적으로 수행할 수 있습니다.

요약

Node.js에서는 클러스터링 및 워커 스레드를 활용하여 병렬 프로그래밍을 수행할 수 있습니다. 이를 통해 CPU 밀도가 높은 작업을 효율적으로 처리할 수 있으며, 성능을 향상시킬 수 있습니다.

참고문헌: