노드에서 멀티 스레드 방식으로 작업할 수 있음.
isMainThread: 현재 코드가 메인 스레드에서 실행되는지, 워커 스레드에서 실행되는지 구분
메인 스레드에서는 new Worker를 통해 현재 파일(__filename)을 워커 스레드에서 실행시킴
worker.postMessage로 부모에서 워커로 데이터를 보냄
parentPort.on(‘message’)로 부모로부터 데이터를 받고, postMessage로 데이터를 보냄
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},
}));
// const worker = new Worker(__filename);
for (let worker of threads){
worker.on('message', (value) => console.log('워커로부터', value));
worker.on('exit', () => {
threads.delete(worker);
if( threads.size == 0){
console.log('워커 끝~');
}
});
// worker.postMessage('ping')
}
} else {//워커스레드
// 우리가 직접 결과물 리턴까지 해줘야함
// 이점은 코드가 동시에 돌아간다.
// parentPort.on('message', (value) => {
// console.log('부모로부터', value);
// parentPort.postMessage('pong');
// parentPort.close();
// })
const data = workerData; // 데이터를 받아옴
parentPort.postMessage(data.start + 100); //
}
예를 들어 소수를 찾는 함수를 작성해보자. 결과는 ??
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.902s
64579
이렇게 나온다면 12초 동안은 아무것도 할 수 없는 것이다.
멀티쓰레드를 이용해보자
const { Worker, isMainThread, parentPort, workerData } = require('worker_threads');
const min = 2;
let primes = [];
// 소수 찾기
function findPrimes(start, range){
let isPrime = true;
let 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 = 10000000;
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: 2.248s
664579
엄청나게 빨라진 것을 볼 수 있다.
자기 컴퓨터에 맞는 thread_count를 찾아서 적용해보자.
'Node.js' 카테고리의 다른 글
파일 시스템 접근하기, 동기와 비동기 메서드 (0) | 2020.12.11 |
---|---|
child_process, 기타 모듈 (0) | 2020.12.11 |
암호화(단방향 :crypto, pbkdf2, 양방향), util (0) | 2020.12.10 |
OS, path, url 모듈 (0) | 2020.12.07 |
노드 내장 알아보기 #2 (0) | 2020.12.04 |