Node.js - 노드 내장 모듈(worker_thread)

ryan·2022년 5월 4일
0
post-custom-banner

WorkerThread

  • 대부분의 작업은 싱글 스레드 환경에서 작업하지만 멀티 스레드를 사용해야 하는 상황이 드물게 발생한다.(암호화 압축)
  • 멀티 스레드 환경을 구성하는 것이 worker_thread module이다.

worker thread 기본적인 사용 방법(멀티스레드 1개)

const {Worker, isMainThread, parentPort} = require('worker_threads');
if (isMainThread) {
  // 메인스레드
  const worker = new Worker(__filename); //
  worker.on('message', (value) => console.log(value)); // worker스레드에서 작업이 완료되면 메세지를 받음
  worker.on('exit', () => console.log('워커 종료')); // worker thread 종료
  worker.postMessage('ping'); // 워커 스레드에게 ping(작업)을 보냄
} else {
  // 워커스레드
  parentPort.on('message', (value) => console.log(value));
  // parentPort를 통해 부로로부터 메세지를 받을 수 있음
  // 부모가 보낸 ping(작업)은 value라는 인자로 받게 됨.
  parentPort.postMessage('pong'); // 부모에게 pong(완료된 작업의 결과값)이라는 메세지를 보냄
  parentPort.close();
}

if문으로 메인 스레드 선언 > 워커 스레드 생성 > 작업 분배 > else문에 워커 스레드 실행 > 워커 스레드 작업 후 메인 스레드로 결과값 전달 > 메인스레드에서 워커스레드 종료(또는 워커스레드에서 워커 스레드 종료) 후 결과물 반환

worker thread 다중 스레드 사용

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

if (isMainThread) {
  const threads = new Set();
  threads.add(
    new Worker(__filename, {
      workerData: {start: 1}, // 초기 데이터가 있을 경우 초기 데이터를 삽입
    })
  );
  threads.add(
    new Worker(__filename, {
      workerData: {start: 2}, // 원하는 만큼 threads constance에 추가
    })
  );
  for (let worker of threads) {
    // 반복문을 통해 작업 진행
    worker.on('message', (value) => console.log(value));
    worker.on('exit', () => {
      threads.delete(worker); // 작업이 종료될 경우 thread에서 worker 삭제
      if (threads.size === 0) {
        // 모든 워커가 종료된 경우
        console.log('워커 종료');
      }
    });
  }
  // 아래와 같이 여러개의 worker constance를 만들어도 기능은 하지만 관리가 어렵기 때문에,
  // 중복되지 않는 배열인 Set instance를 통해 관리한다.
  // const worker = new Worker(__filename);
  // const worker2 = new Worker(__filename);
  // const worker3 = new Worker(__filename);
  worker.on('message', (value) => console.log(value));
  worker.on('exit', () => console.log('워커 종료'));
} else {
  const data = workerData; // 위에서 설정한 초기데이터는 workerData를 통해 받아올 수 있음
  parentPort.postMessage(data.start + 100); // 구체적인 작업 실행
}
  • 다중 스레드의 경우 각 스레드를 새로운 constance에 할당하는 것보다 Set을 통해 배열로 관리하는 것이 편하다.
  • 워커 스레드에서 작업이 완료된 경우 해당 워커 스레드를 삭제하는 메서드를 추가해줘야 한다.
profile
프론트엔드 개발자
post-custom-banner

0개의 댓글