비동기 메서드들은 백그라운드에서 실행되고, 실행된 후에는 다시 메인 스레드의 콜백 함수나 프로미스의 then 부분이 실행된다. fs의 메서드들이 그 예중의 하나이다. 여러 번 실행해도 백그라운드에서 동시에 처리되는데, 바로 스레드풀이 있기 때문이다.

fs 외에도 내부적으로 스레드풀을 사용하는 모듈로는 crypto, zlib, dns, lookup 등이 있다.

crypto를 이용한 예제

const crypto = require('crypto');

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

crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`1 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`2 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`3 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`4 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`5 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`6 : ${(end - start) / 1000} s`);
})
crypto.pbkdf2(pass, salt, 1000000, 128, 'sha512', () => {
  const end = Date.now();
  console.log(`7 : ${(end - start) / 1000} s`);
})

Untitled

실행할 때마다 시간과 순서가 다르다. 스레드풀이 작업을 동시에 처리하므로 작업중에서 어느 것이 먼저 처리될지 모른다. 하지만 규칙이 좀 있는데 1~4가 먼저 나오고 그 이후에 5~7이 출력된다. 기본적인 스레드풀의 개수가 4개라 그렇다. 처음 4개 작업부터 동시에 실행되고, 그것들이 종료되면 다음 작업이 실행된다. 만약 컴퓨터의 코어 개수가 4보다 작으면 결과가 다를 수도 있다.

스레드풀을 직접 컨트롤할 수는 없지만 개수를 조절할 수는 있다.

#윈도우, 명령 프롬프트를 연 후 아래처럼 입력
SET UV_THREADPOOL_SIZE=1

#맥과 리눅스의 경우 터미널에 아래처럼 입력
UV_THREADPOOL_SIZE=1