반응형
# 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 : 가상 머신에 직접 접근할 때 사용.
반응형
'인프런 강의 학습 > Node.js 교과서' 카테고리의 다른 글
Node.js 학습_스레드풀과 커스텀 이벤트 / 에러 처리 (0) | 2021.10.04 |
---|---|
Node.js 학습_파일 시스템(fs) 모듈 / 버퍼와 스트림 / pipe와 스트림 메모리 효율 확인 (0) | 2021.10.03 |
Node.js 학습_노드 내장모듈 (0) | 2021.10.03 |
Node.js 학습_REPL 사용 / JS파일 실행 / 모듈 생성 / 노드 내장 객체 (0) | 2021.10.02 |
Node.js 학습_자바스크립트 문법(화살표 함수) (0) | 2021.10.02 |