Single Thread & event loop
in JavaScript
매번 나올때마다 이해안됐던 싱글스레드(=단일스레드)와 이벤트 루프의 종지부다.
Single Thread
자바스크립트 엔진은 단 하나의 실행컨텍스트를 갖는다.
이 말은, 함수를 실행할 수 있는 창구가 다 하나이므로 동시에 2개 이상의 함수를 실행할 수 없다는 말이다.
그래서 만약 실행되어야 할 함수가 10개가 쌓여있다면,
지금 당장 실행되고있는 함수를 제외하고는 모두 ‘실행 대기 중인 태스크들’이다.
이렇게 한번에 하나의 태스크만 실행할 수 있는 방식을 싱글 스레드라고 하는데,
이렇게 한번에 하나의 태스크만 실행하면 태스크중에 시간이 걸리는 태스크를 실행하게 되면 블로킹(작업중단)현상이 일어날 수 있다는 단점이 있다
그래서 나온 개념이 동기/비동기 개념이다
Synchronous (동기)
동기는 실행순서가 보장된다는 장점이 있지만 앞선 태스크가 종료될때까지 이후 태스크들이 블로킹된다는 단점이 있다
Asynchronous (비동기)
비동기는 현재 실행중인 태스크가 종료되지 않은 상태라고 해도 바로 다음 태스크를 실행한다.
그래서 동기와는 반대로 블로킹이 발생하지 않는다는 장점이 있는 반면 태스크의 실행순서가 보장되지 않는다는 단점이 있다.
타이머함수인 setTimeout
, setInterval
, HTTP요청
, 이벤트핸들러
는 비동기 처리방식으로 동작한다
event loop
비동기처리는 이벤트 루프와 깊은 관계가 있다.
위에 말한것처럼 자바스크립트는 싱글 스레드로 동작한다. 하지만 브라우저가 동작하는 것을 살펴보면 동시에 많은 태스크가 처리되는 것처럼 느껴지는데,
이것은 옳게 느낀게 맞다.
자바스크립트는 싱글 스레드 방식으로 동작하지만, 브라우저는 아니기 때문이다.
무슨 말이냐면..
싱글스레드 방식으로 동작하는것은 브라우저가 아니라 브라우저에 내장된 자바스크립트 엔진이라는 것이다.
브라우저는 실제로 멀티 스레드로 동작한다.
이렇게 자바스크립트의 동시성을 지원하는것이 바로 이벤트 루프이다.
이벤트루프는 브라우저에 내장되어 있는 기능 중 하나인데,
이벤트 루프에 대해 설명하자면,
이벤트 루프는 콜 스택에 현재 실행중인 실행 컨텍스트가 있는지, 그리고 태스크큐에 대기중인 함수가 있는지 반복해서 확인한다.
만약 콜 스택이 비어있는데 태스크 큐에 대기중인 함수가 있다면 이벤트 루프는 순차적으로(FIFO)
태스크 큐에 대기중인 함수를 콜 스택으로 이동시킨다.
- 힙 : 객체가 저장되는 메모리 공간
- 콜 스택 : 실행 컨텍스트 스택. 함수가 실행된다는 말은 콜 스택에 함수가 푸시된다는 말과 같다
이렇게 콜 스택과 힙으로 구성되어 있는 자바스크립트 엔진은 단순히 태스크가 요청되면 콜 스택을 통해 요청된 작업을 순차적으로 실행할 뿐이다.
_φ( °-°)/.. 잘 알아두어야하는게,
비동기처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저
와 node.js
가 담당한다
예를 들어
콜백함수의 평가와 실행은 JS엔진이 담당하지만, 타이머설정이나 콜백함수 등록같은 소스코드의 평가와 실행을 제외한 모든 처리는 브라우저와 node.js가 담당한다는 것이다.
그래서 이를 위해서 브라우저 환경은 태스크 큐와 이벤트 루프 기능을 제공하는 것이다.