본문 바로가기

Programming/Node.js

4. Node 기능 살펴보기 (4) - 노드 내장 모듈 9 [worker_threads] 4(★)

node js logo image

 

 

 

 

 

앞서서 워커 스레드를 사용해 보기 위한 예제로, 2부터 10000000 사이의 숫자 중 소수(prime number)를 구하는 코드를 만들어 보았습니다. 중첩 for문을 활용한 예제였는데, 이제 이것을 스레드를 활용하여 구현해 보도록 하겠습니다. 

 

 

 

4. Node 기능 살펴보기 (4) - 노드 내장 모듈 9 [worker_threads] 3

앞의 아티클까지 살펴본 메인/워커 스레드 사용 방식을 조금 더 응용하여, 더 복잡한 내용을 다루어보도록 하겠습니다. 꽤 어려운 내용이 될 것이니 감안하고 읽어나가시기 바랍니다.  우선,

nozeroslope.tistory.com

 

 

const min = 2;
const max = 10000000;
const 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;
    }   
}

console.time('prime');
findPrimes(min, max);
console.timeEnd('prime');
console.log(primes.length);

/* 출력
prime: 3.393s
664579
*/

 

 

 


 

 

 

 

Math.floor() - JavaScript | MDN

Math.floor() 함수는 주어진 숫자와 같거나 작은 정수 중에서 가장 큰 수를 반환합니다.

developer.mozilla.org

 

 

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; i < 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;      // 8개의 스레드가 일을 나눠 처리하도록
    const threads = new Set();
    const range = Math.floor( (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;
        // console.log(i , 'start :', start);
    }

    threads.add(new Worker(__filename, { workerData: { start, range: max - start } }));
    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);
}