JS/TIL(Today I Learned)

2025-02-26

프린스 알리 2025. 2. 26.

child_process 모듈 개요

child_process 모듈은 Node.js에서 외부 프로세스를 실행하고, 해당 프로세스와 데이터를 주고받을 수 있도록 해준다. 이 모듈을 이용하면 Node.js 프로세스 내에서 다른 스크립트나 명령어를 실행할 수 있으며, 게임 서버를 분리된 프로세스로 실행하거나, 특정 작업을 병렬적으로 처리하는 데 유용하다.

이 모듈은 네 가지 주요 방식으로 외부 프로세스를 생성할 수 있다.

 

  1. exec - 명령어 실행 후 결과를 한 번에 반환한다.
  2. execFile - 특정 파일을 실행하고 결과를 반환한다.
  3. spawn - 프로세스를 실행하고 스트림을 사용하여 데이터와 상호작용할 수 있다.
  4. fork - spawn과 비슷하지만 Node.js 스크립트를 실행하는 데 특화된 방식이다.

1. exec 사용법

import { exec } from 'child_process';

exec('ls -la', (error, stdout, stderr) => {
  if (error) {
    console.error(`에러 발생: ${error.message}`);
    return;
  }
  if (stderr) {
    console.error(`stderr: ${stderr}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
});

설명

  • exec는 쉘을 사용하여 명령을 실행한다.
  • 결과를 한 번에 받아오므로 출력이 많은 경우 메모리 부담이 있을 수 있다.

2. execFile 사용법

import { execFile } from 'child_process';

execFile('/bin/ls', ['-la'], (error, stdout, stderr) => {
  if (error) {
    console.error(`에러 발생: ${error.message}`);
    return;
  }
  if (stderr) {
    console.error(`stderr: ${stderr}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
});

설명

  • execFile은 특정 실행 파일을 실행할 때 사용된다.
  • 쉘을 거치지 않기 때문에 exec보다 보안성이 뛰어나고 성능이 좋다.

3. spawn 사용법 (대규모 데이터 처리에 적합)

import { spawn } from 'child_process';

const ls = spawn('ls', ['-la']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`프로세스 종료 코드: ${code}`);
});

설명

  • spawn은 스트림을 통해 데이터를 주고받을 수 있다.
  • 대량의 데이터를 처리해야 할 때 유용하다.

4. fork 사용법 (Node.js 스크립트 실행에 적합)

import { fork } from 'child_process';

const child = fork('child.js');

child.on('message', (msg) => {
  console.log(`부모 프로세스가 받은 메시지: ${msg}`);
});

child.send('Hello from parent');

child.js

process.on('message', (msg) => {
  console.log(`자식 프로세스가 받은 메시지: ${msg}`);
  process.send('Hello from child');
});

설명

  • fork는 Node.js 스크립트를 별도 프로세스로 실행할 때 사용된다.
  • 부모와 자식 프로세스 간 메시지를 주고받을 수 있다.

child_process를 이용한 게임 서버 분리 실행 예제

멀티플레이 게임 서버에서 던전이나 인스턴스를 별도 프로세스로 관리하려면 spawn 또는 fork를 사용할 수 있다.

던전 서버를 개별 프로세스로 실행

import { fork } from 'child_process';

function startDungeonInstance(dungeonId) {
  const dungeonProcess = fork('./dungeonInstance.js', [dungeonId]);

  dungeonProcess.on('message', (msg) => {
    console.log(`던전 서버 (${dungeonId}) 메시지:`, msg);
  });

  dungeonProcess.on('exit', (code) => {
    console.log(`던전 서버 (${dungeonId}) 종료 코드: ${code}`);
  });

  return dungeonProcess;
}

const dungeon1 = startDungeonInstance(1);
const dungeon2 = startDungeonInstance(2);

dungeonInstance.js

const dungeonId = process.argv[2];

console.log(`던전 인스턴스 ${dungeonId} 시작`);

setInterval(() => {
  process.send(`던전 ${dungeonId} 상태 업데이트`);
}, 5000);

process.on('message', (msg) => {
  console.log(`던전 ${dungeonId}가 받은 메시지: ${msg}`);
});

정리

  • 작업을 한 번 실행하고 결과를 받을 경우 → exec 또는 execFile
  • 대량의 데이터를 처리하는 경우 → spawn
  • Node.js 스크립트를 실행하고 메시지 교환이 필요한 경우 → fork

멀티플레이 게임 서버에서 던전, 인스턴스, 채널 서버 등을 독립된 프로세스로 실행하고 싶다면 fork를 활용하는 것이 효과적이다.

댓글