개발자가 내팔자

이벤트 루프에 대해 알아보자 본문

WEB

이벤트 루프에 대해 알아보자

야생의 개발자 2022. 8. 2. 04:52

( 이 글은 2021년 8월에 작성된 글입니다. )

 

JS 이벤트루프를 이해하기 위해서는 아래와 같은 몇가지 기반 지식이 선행되면 좋다.

그러므로 아래의 순서대로 이야기를 진행해보겠다.

 

1. 자료구조 스택, 큐

2. 프로세스와 스레드

3. 자바스크립트 동작 원리

 

 

1. 자료구조 Stack, Queue

 

맛있겠다...

What is Stack ?

스택은 프링클스 통을 생각하면 쉽다.

들어갈 땐 첫 번째였겠지만 나갈 땐 가장 마지막에 나간다.

(First In Last Out)

그리고 가장 마지막에 들어간 과자가 가장 먼저 꺼내진다.

(Last In First Out)

 

 

What is Queue ?

큐는 화장실 줄 서기를 생각하면 쉽다.

먼저 들어간 사람이 먼저 나온다.

(First In First Out)

때로는 너무 급한 사람에게 자리를 양보하기도 한다.

이건 우선 순위 큐라고 한다.

오늘은 중요하지 않으므로 이 이상 이야기하지 않겠다.

 

 

 

 

 

2. Process Thread

What is Process ?

프로세스는 메모리에 올라와 실행중인 프로그램을 말한다.

구조는 왼쪽과 같다. 텍스트 영역에는 소스코드가 들어간다.

데이터 영역에는 전역 변수, 정적 변수 등이 들어간다.

여기서 중요한 것은 스택, 그리고 힙이다.

스택은 위에서 이야기했던 바로 그 스택구조로 이루어져있다.

코드가 실행되면서 스택이 푸쉬푸쉬 쌓이고,

실행이 완료되며 팝! 하고 제거된다.

힙 영역에는 좀 더 보존되길 원하는 데이터를 동적으로 할당하는 곳이다.

메모리 누수가 나기 좋은 곳이기 때문에 개발자는 항상 주의해야 한다.

인간의 욕심은 끝이 없고... 한 번에 여러개의 일을 하고 싶어진다.

글쓴이도 지금 맥북으로 노래를 켜놓고 가끔 카톡도 확인하면서 블로그에 글을 쓰고 있다. 어떻게 이 많은 프로그램이 한 번에 실행되는 걸까? 사실은 한 번에 하나만 처리된다(cpu 코어 한개 기준. 코어가 여러 개면 정말로 병렬적인 처리를 할 수 있다.) 우리가 눈치채지 못할만큼 빠르게 컨텍스트 스위칭(문맥 교환)을 하며 이거 했다, 저거 했다를 반복하는 것이다.

 

(추후에 멀티태스킹, 멀티 프로세스, 멀티 스레드에 대한 글을 쓰고 싶다)

 

 

 

What is Thread ?

인간의 욕심은 끝이 없고.. 한 번에 여러가지 일을 동시에 처리하고 싶은 욕망에 사로잡힌다. 그래서 프로세스의 스택 영역을 잘게 쪼개버리는데, 이것이 바로 스레드(thread)다! 프로세스끼리는 서로 통신하기 힘들게 만들어져있다. 통신이 쉽게 되면 그건 해킹으로 이어질 수 있기 때문이다. 하지만 아주 불가능하지는 않다. IPC(InterProcess Commication)이라는 특수한 방법들 중 하나를 이용하면 된다. (추후에 블로그에 올리겠다.) 그런데 스레드는 스택과 레지스터만 분리되어 있을 뿐, 나머지 영역들은 공유하기 때문에 별다른 특수한 방법 없이도 자유롭게 소통할 수 있다. 즉, 소통에 비용이 적게 들어 보다 더 빠르게 협업할 수 있다는 뜻이다. 물론, 동기화 문제가 발생하기도 하지만 뮤텍스나 세마포어에 대해 공부해보면 이를 해결한 방법이 있다는 것을 알게 될 것이다.

 

스레드는... 솔직히 오징어처럼 생겼다. 다리 하나 하나가 스레드

 

 

 

 

3. 자바스크립트의 동작 원리

여러분은 이런 말을 들어본 적이 있는가?

자바스크립트는 싱글 스레드다.

맞다. 프로세스는 스택을 쪼개서 저렇게 많은 멀티 스레드를 만들어서 업무 분담을 통해 빠르고 효율적인 일처리를 해냈는데, 자바스크립트는 단일 스레드라고 한다. 그런데 어떻게 그렇게 빠르게 동작할 수 있을까? 정말 놀랄 일이다.

그런데 잠깐, 여러분은 혹시 이 말도 들어본 적이 있는가?

자바스크립트가 비동기 언어다.

여기서 비동기란, 순서대로 움직이지 않는다는 것이다. 동시에 여러개를 할 수 있다. 도대체 자바스크립트는 어떻게 생겨먹었길래 스레드가 하나인데 동시에 여러가지 일을 할 수 있는 것일까? 이벤트루프가 오늘의 해답이 될 것 같다. 이벤트루프가 돌아가는 모습을 보여주며 설명하고 싶은데 영상이 아니라 글로만 설명된 것을 보고 잘 이해할 수 있을지 걱정이 된다. 추후에 이에 관한 영상을 찍어 올리도록 하겠다.

보통은 콜스택 옆에 힙도 그려져 있는데 이 그림엔 안 나와있다. 사실 이벤트루프를 이해하는데는 별로 중요하진 않다.

자바스크립트는 V8과도 같은 자바스크립트 엔진에 의해서 평가단계를 거쳐 실행된다. 실행 컨텍스트와 렉시컬 스코프에 대한 이야기를 자세히 하고 싶어서 손가락이 간질간질하지만 이벤트 루프를 이해하기엔 너무 과한 내용이고 마감까지 3시간밖에 남지 않았으니 다음 기회로 미루도록 한다. 실행될 때마다 콜 스택(실행 컨텍스트 스택이라고도 함)에 실행 컨텍스트가 하나씩 푸시되고, 실행이 완료되면 팝되면서 사라진다. 이 때 탑이 가리키고 있는, 최상단에 있는 실행 컨텍스트를 실행중인 실행 컨텍스트라고 한다. setTimeout이나 setInterval같은 브라우저에서 제공하는 API를 이용하는 코드가 있다면 이는 바로 팝되어 Web API단으로 넘어간다. 타이머에 맞춰서 지정한 시간이 지난 뒤에 태스크 큐(콜백 큐라고도 한다)에 등록되어 쌓인다. 코드를 실행하는 중에 프라미스를 쓰는 부분이 있다면 그것은 마이크로태스크 큐에 들어가서 쌓인다. 여기서 큐는 아까 스택과 큐에 대해서 설명할 때 봤던 바로 그 큐다.

 

저렇게 큐에 쌓인 것들은 이벤트루프가 허락할 때까지 그곳에서 대기한다. 이 때 이벤트 루프가 신경쓰는 것은 콜스택이 비어있는지다. 이벤트루프는 계속 다이얼처럼 계속 빙글빙글 돌면서 각각의 상태를 확인하여 푸시한다. 이벤트 루프는 초원의 암사자처럼 콜스택을 지켜보다가, 비어 있는 것이 확인되면 태스크 큐에 있는 실행 컨텍스트를 하나씩 콜스택에 푸시한다. 마이크로태스큐에 있는 콜백 함수들은 콜백 큐와 다르게 마이크로태스크 큐가 완전히 빌 때까지 콜스택에 계속 푸시된다. 애니메이션 큐에는 Request Animation Frame이라는 API에 등록된 콜백함수를 실행하여 리렌더링이 될 때까지 실행 컨텍스트가 쌓이게 되는 것 같다.(이 부분은 나도 안써봐서 잘 모름) 이벤트 루프가 일정 주기마다 확인을 하면서 바뀌어야 할 부분들이 쌓여있으면 60프레임 속도에 맞춰서 렌더트리를 재구성하고 리플로우->리페인팅 과정을 거쳐 리렌더링을 해주는 것 같다.

 

여기까지가 이벤트루프에 대한 이야기였다. 결국 자바스크립트 엔진은 싱글 스레드지만 브라우저라는 호랑이 등에 업혀가기 때문에 비동기적으로 움직일 수 있었던 것이었다. 시간 내서 이 글을 읽은 모든 분들이 이제는 이벤트루프에 대해 이해가 잘 됐으면 좋겠다. 부족하거나 어려운 부분이 있었다면 댓글로 남겨주면 보충하도록 하겠다.

 

 

'WEB' 카테고리의 다른 글

브라우저 동작 원리를 알아보자  (0) 2022.08.02
[HTTP] Response에 대해 알아보자  (0) 2022.06.13
[HTTP] 요청과 응답  (0) 2022.05.24
[Tomcat] 설정 파일  (0) 2022.05.24
[Java] HttpServletMethod  (0) 2022.05.23
Comments