Node.js에서 독립적인 프로세스를 통한 연산 및 그 결과 얻기

독립적인 프로세스를 통해 얻는 장점은 여러 개의 CPU를 활용하여 보다 더 빠른 결과를 얻을 수 있다는 점인데, 단점은 CPU 간의 데이터 공유가 참조(Reference)가 아닌 복사(Copy)이므로 메모리 사용량이 2배가 된다는 점이다. 하지만 이러한 단점은 특정한 상황에서는 아무런 문제가 되지 않는 경우가 있으므로 Node.js에서 독립적인 프로세스를 이용한 연산은 매우 유용한 경우가 많다.

먼저 독립적인 프로세스에서 수행할 코드는 worker.js 파일에 다음처럼 작성한다.

const process = require("process");

function getSum(arr) {
    let sum = 0;
    arr.forEach(i => {  sum += i; });
    return sum;
}

process.on("message", (message) => {
    if(message.cmd === "sum") {
        process.send({ result: getSum(message.data) });
    }
});

getSum이라는 함수를 처리하며 다른 프로세스로부터 전달 받은 데이터(배열 형태) 안의 숫자 값들의 합계를 전달해 준다.

이 worker.js를 사용하는 소스는 다음과 같다.

const cp = require("child_process");
const worker = cp.fork("./worker.js");

function task(arr) {
    return new Promise((resolve, reject) => {
        function onMessage(message) {
            resolve(message.result);
            worker.removeListener("message", onMessage);
        }

        worker.addListener("message", onMessage);

        worker.send({ 
            cmd: "sum",
            data: arr
        });
    })
}

task([1,2,3,4,5,6,7,8,9,10])
    .then((result) => {
        console.log(result);
        worker.kill();
    })
    .catch(err => {
        console.log(err);
    });

4번 코드에서 독립적인 프로세스에서 수행된 결과를 얻기 위해 Promise API를 사용했다는 점. 20번 코드에서 Prmoise의 일반적인 처리를 위해 then, catch를 사용하여 정상적인 경우와 예외처리를 하고 있다는 점이 코드의 완결성을 느끼게 해준다.

Node.js에서 fork를 사용해 독립적인 프로세스를 통한 연산

이전에 아래의 포스트를 통해 Node.js에서 스레드를 사용해 연산을 처리한 글을 올렸습니다.

Node.js에서 Thread 사용

이번에는 별도의 독립적인 프로세스를 통한 연산 수행해 그 결과를 얻는 코드에 대해 정리합니다. 위의 글과 동일한 기능을 구현하며 Thread 대신 Process를 이용한다는 차이점만 있습니다./p>

서버에 대한 코드는 다음과 같습니다.

const express = require("express");
const app = express();

const { fork } = require("child_process");

app.get("/", (req, res) => {
    const child = fork("./task.js");
    
    child.send("start");

    child.on("message", (sum) => {
        res.send({sum: sum});
    })
});

app.listen(3000);

외부 프로세스에서 수행할 연산에 대한 코드는 task.js 파일에 정의되는데.. 아래와 같습니다.

process.on("message", (message) => {
    if(message === "start") {
        let total = 0;

        for(let i=0; i<10000000000; i++) {
            total++;
        }
        
        process.send(total);
    }
})