본문 바로가기

Programming/Node.js

4. Node 기능 살펴보기 (9) - 스레드 풀

node js logo image

 

 

 

 

앞선 아티클에서 살펴본 fs 모듈의 메서드들은 비동기 메서드였습니다. 정리하면, 비동기 메서드들은 백그라운드에서 실행되고 > 실행된 후 메인 스레드의 콜백 함수 or 프로미스의 then 부분이 실행됩니다. 이때 fs 메서드가 여러번 실행되어도, 스레드 풀의 존재로 인해 fs 메서드는 백그라운드에서 동시에 처리가 됩니다. 

 

fs외에도 crypto, zlib, dns.lookup 등의 모듈은 스레드 풀을 내부적으로 사용합니다. 아래 예제에서 crypto.pbkdf2 메서드를 통해서 스레드 풀의 존재를 확인해 보겠습니다. 

 

const crypto = require('crypto');

const pass = 'pass';
const salt = 'salt';
const start = Date.now();

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('1:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('2:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('3:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('4:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('5:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('6:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('7:', Date.now() - start);
});

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
    console.log('8:', Date.now() - start);
});

/* 출력
2: 2087
4: 2192
1: 2228
3: 2413
5: 4373
6: 4399
8: 4556
7: 4579
*/

 

 

 

위와 같은 실행 결과를 보여주는데, 스레드 풀이 동시에 작업을 처리하기 때문에 여덟 개의 작업 중에서 어느 것이 먼저 처리될지는 알 수 없습니다. 기본적인 스레드 풀의 개수는 네 개이기 때문에, 1~4와 5~8이 각각 그룹으로 묶여 실행된다는 규칙은 있습니다. 또한 5~8이 시간이 소요가 더 됩니다. 스레드 풀 네 개가 먼저 실행되기 때문이죠.(PC의 코어 개수에 따라 달라집니다)

 

스레드 풀은 위의 설명처럼 직접 조작은 불가하지만, 스레드 풀 개수 자체는 변경이 가능합니다. 윈도우의 경우 SET UV_THREADPOOL_SIZE=1을 프롬포트에 입력합니다. 맥이나 리눅스의 경우 터미널에 UV_THREADPOOL_SIZE=1을 입력하고 다시 위 파일을 실행하면 작업은 순서대로 진행됩니다. 스레드 풀 개수가 1개로 제한되었기 때문이죠. 

 

참고로 위 명령은 process.env.UV_THREADPOOL_SIZE를 설정하는 명령어 입니다.