Node.js 학습_노드 내장 객체 worker_threads / child_process

Node.js 학습_노드 내장 객체 worker_threads / child_process

728x90

반응형

# worker_threads

노드에서 멀티 스레드 방식으로 작업할 수 있음. (암호화, 압축 작업 말고는 대부분 싱글 스레드를 함)

isMainThread : 현재 코드가 메인 스레드에서 실행되는지, 워커 스레드에서 실행되는지 구분

메인 스레드에서는 new Worker를 통해 현재 파일(__filename)을 워커 스레드에서 실행시킴

worker.postMessage로 부모에서 워커로 데이터를 보냄

parentPort.on('message')로 부모로부터 데이터를 받고, postMessage로 데이터를 보냄

console.log('--------------worker_threads-------------') const { isMainThread, parentPort } = require('worker_threads'); if (isMainThread) { // 메인스레드 const worker = new Worker(__filename); worker.on('message', (value) => console.log('워커로부터', value)); worker.postMessage('ping'); } else { // 워커스레드 parentPort.on('message', (value) => { console.log('부모로부터', value); parentPort.postMessage('pong'); parentPort.close(); }); }

worker 여러개 생성해서 하는 예 (싱글워커)

console.log('--------------worker_threads-------------') 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 }, })); for (let worker of threads) { worker.on('message', (value) => console.log('워커로부터 ', value)); worker.on('exit', () => { threads.delete(worker); if (threads.size === 0) { console.log('워커 끝~'); } }); } } else { // 워커스레드 const data = workerData; parentPort.postMessage(data.start * 100); }

worker_threads 사용 2 ~ 천만 사이 소수찾는 예

const min = 2; const max = 10_000_000; const primes = []; // 에라토스테네스의 체 function generatePrimes(start, range) { let isPrime = true; const end = start + range; for (let i = start; i < end; i++) { for (let j = min; j < Math.sqrt(end); j++) { if (i !== j && i % j ===0) { isPrime = false; break; } } if (isPrime) { primes.push(i); } isPrime = true; } } console.time('prime'); generatePrimes(min, max); console.timeEnd('prime'); console.log(primes.length); 출력 결과 prime: 11.416s 664579

각 워커에게 일 분배를 해주는 코드를 짜야함. (멀티 스레드 사용)

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); const min = 2; let primes = []; function findPrimes(start, range) { let isPrime = true; const end = start + range; for (let i = start; i < end; i++) { for (let j = min; j < Math.sqrt(end); j++) { if (i !== j && i % j ===0) { isPrime = false; break; } } if (isPrime) { primes.push(i); } isPrime = true; } } if (isMainThread) { const max = 10_000_000; const threadCount = 8; const threads = new Set(); const range = Math.ceil((max - min) / threadCount); let start = min; console.time('prime'); for (let i = 0; i < threadCount - 1; i++) { const wStart = start; threads.add(new Worker(__filename, { workerData : { start : wStart, range }})); start += range; } threads.add(new Worker(__filename, { workerData : { start, range : range + ((max - min + 1) % threadCount)}})); for (let worker of threads) { worker.on('error', (err) => { throw err; }); worker.on('exit', () => { threads.delete(worker); if (threads.size === 0) { console.timeEnd('prime'); console.log(primes.length); } }); worker.on('message', (msg) => { primes = primes.concat(msg); }); } } else { findPrimes(workerData.start, workerData.range); parentPort.postMessage(primes); } 출력 결과 prime: 1.854s 664579

멀티 스레드를 Node 보다는 다른 언어로 하는게 좋음.

# child_process

const exec = require('child_process').exec; var process = exec('dir'); process.stdout.on('data', function (data) { console.log(data.toString()); }); process.stderr.on('data', function (data) { console.error(data.toString()); });

spawn.js 에서 test.py 호출 예 (단, 다른 언어를 호출 할 때는 해당 언어가 설치되어있어야 함_노드가 실행 요청을 하는 것.)

# spawn.js 파일 const spawn = require('child_process').spawn; const process = spawn('python', ['test.py']); process.stdout.on('data', function (data) { console.log(data.toString()); }); process.stderr.on('data', function (data) { console.error(data.toString()); }); # test.py 파일 print('hello python') node spawn 실행 시 출력 결과 hello python

# 기타 모듈

assert : 값을 비교하여 프로그램이 제대로 동작하는지 테스트하는 데 사용.

dns : 도메인 이름에 대한 IP 주소를 얻어내는데 사용.

net : HTTP 보다 로우 레벨인 TCP 나 IPC 통신을 할 때 사용.

string_decoder : 버퍼 데이터를 문자열로 바꾸는 데 사용.

tls : TLS와 SSL에 관련된 작업을 할 때 사용.

tty : 터미널과 관련된 작업을 할 때 사용.

dgram : UDP와 관련된 작업을 할 때 사용.

v8 : V8 엔진에 직접 접근할 때 사용.

vm : 가상 머신에 직접 접근할 때 사용.

728x90

반응형

from http://dlagusgh1.tistory.com/834 by ccl(A) rewrite - 2021-10-03 17:26:39