Node.js 이벤트루프와 싱글스레드

juhojung·2022년 8월 31일
0

nodejs

목록 보기
6/6
post-thumbnail

Nodejs 는 싱글스레드 논블로킹(I/O) 이다.
기본적으로 스레드와 프로세스개념을 안다는 가정하에,
우리는 싱글스레드라면 특정 일(job)을 하고있을때에 다른일을 못한다는 것을 알고 있다.
그런데 Nodejs 는 어떻게 하나의 스레드로 I/O 가 발생했을때 비동기적으로 처리가 가능할까?

Node.js Event Loop


노드.js 는 이벤트 루프를 기반으로 모든 프로세스가 진행된다.
설명하기에 앞서, 각각에 페이즈별로 진행하는것으로 유도하는 함수들이 있다.
함수들과 페이즈를 매칭시켜가면서 읽으면 좋다.
Timer - Pending Callbacks - Idle, Prepare - Poll - Check- Close Callback - Timer
각 페이즈 사이에 - 부분 즉 넘어가는 곳을 Tick 이라고 한다. (process.nextTick())
각각에 페이즈별로 어떤일을 하는지 아래에 간략하게 설명한다.

Timer Phase :

타이머들을 다루는 함수로, setTimeout, setInterval 같은 특정시간 이후의 실행되는 것들에 대해 저장해놓고, 빼서 검증하는 페이즈이다.

저장하는곳은 Min-Heap 이다. 이진트리로 이루어져있는 데이터 저장소인데, 최대값, 최소값을 구하는데 효율적인 자료구조라고 한다.
타이머의 설정한 시간 오름차순으로 저장하기에, 위에서부터 검사하면서 false 가 나오면 바로 탐색을 중단한다.
이처럼 페이즈가 도달할때마다 체크하기에 setTimeout(func, 1000) 코드를 작성해도 정확히 1000ms 후에 실행되지 않는다. (이벤트루프, 타이머 페이즈 실행시간이 추가된다.)
실행할 수 있는 모든 작업을 하거나, 실행 한도에 다다르면 다음 페이즈인 Pending Callbacks 로 넘어간다.
실행 한도란 Node에서 한 페이즈에서 가능한 최대 수치를 말하는데, 정확한 숫자로는 표현할수없다. 왜냐하면 매우 다양한 곳에서 이벤트를 호출하고있고, 비동기적인 처리를 여러방면으로 (I/O, tick event) push 하고있기에, 작업한도는 불규칙적으로 변화한다.
단, V8 엔진의 최대 힙 사이즈를 늘린다면 실행한도를 늘릴수있다.
toobusy 라이브러리를 통해 체크할 수 있다.

Pending Callbacks Phase :

pending-queue 에담기는 callback 을 관리

Idle, Prepare Phase :

코드의 직접적인 실행결과에 영향을 끼치지 않는 상태이며, Node.js 의 내부적인 관리를 위한 상태이다.

Poll Phase :

Timer Phase에서 실행하지 않는 모든함수들, I/O가 실행된다.

Check Phase :

setImmediate 함수의 콜백에 담긴 함수를 실행한다. 이로써 process.nextTick 함수는 즉시실행 되고, setImmediate 함수는 다음 틱에 실행 되는걸 알수있다. 두개의 함수명이 바뀐게 아니냐는 말이 포럼에서 많이들 얘기한다.

Close Callbacks Phase :

socket.on('close', () => {}); 과 같은 close 이벤트 타입의 핸들러를 처리하는 페이즈.
정확하게는 uv_close()를 부르면서 종료된 핸들러의 콜백들을 처리하는 페이즈다

현재 업데이트중

참고 사이트
https://www.korecmblog.com/node-js-event-loop/
: 훨씬 상세하게 잘 정리해주신 블로그. 딥하게 이해하기 좋은 글이었습니다.
https://github.com/lloyd/node-toobusy

profile
"어찌 할 수 없는 일에 대해 고민하는 시간은 낭비일 뿐이다."

0개의 댓글