[node.js] Javascript 동작원리 - 싱글스레드 / 이벤트루프

1. Javascript의 동작기초

Javscript의 동작기초를 이해하기 위해선 비동기처리 및 non-blocking 개념을 먼저 이해해야 한다.

비동기처리

비동기처리는 순차실행과 상반되는 개념으로, 앞선 코드의 온전한 실행 및 종료를 기다리지 않고 다음 코드를 실행하는 것을 일컫는다.

물론 javscript 엔진이나 node.js도 마찬가지로, 기본적으로 코드실행(메모리 힙이나 call-stack에 명령이 할당되어 실행하기까지의 과정)은 순차적으로 진행된다.

그러나 python과는 달리 javascript 엔진을 구동하는 node.js 등에선 비동기처리 함수(API)를 지원하기 때문에, 비동기처리가 가능하다.

정리하면, 먼저 나타난 함수의 return이 완료될 때까지 기다리지 않고 그 이후의 코드를 실행하는 것이 비동기처리이다(상반되는 개념은 동기처리).

비동기처리는 이를 지원하는 API 및 함수처리를 통해 가능하다.

※ 병렬처리의 경우 싱글스레드보다는 멀티스레드의 개념에 가깝고, 비동기처리와는 다른 개념이므로 유의.

non-blocking

프로세스의 실행보류를 하지 않고, 지속 실행을 하는 상태를 의미한다.

리눅스에서 프로세스가 실행중인 상태에서 file I/O 및 기타 시스템함수 호출 시, 해당 함수를 실행하기위해 실행중인 프로세스를 보류상태(blocking)로 전환한다.

non-blocking은 이와 상반되는 개념으로, 프로세스 실행을 보류하지 않는다.

비동기처리 관점에서 보면,

setTimeout({
  console.log("시작2")
},0)

console.log("시작1")

위 코드를 실행할 경우 시작1 -> 시작2 순으로 출력된다.

logic 순서는 setTimeout -> 시작1 출력 -> 지연시간후 시작2 출력의 순으로 진행하는데, 시작1을 출력하는 console.log logic 실행을 할 때 setTimeout(시간지연)호출이 되었어도 전체 logic의 실행을 중단하지 않는다.

즉 setTimeout 비동기API를 호출한 시점에서, 해당 코드 및 전체적인 logic은 지속되고 있다.

이러한 실행지속을 non-blocking이라 하며, node.js에서 비동기처리가 구현될 수 있도록 하기위한 중요 연관개념이다.

※※ 동기처리를 할 경우 return 시점에서 이후 logic을 실행하는 것을 보장하기 위해 다른 코드들을 blocking 처리하게 된다.

2. event loop

특정 event가 발생하는 시점에서 처리하는 과정

Javscript가 비동기처리를 할 수 있는 원리는 event loop 구조를 살펴보면 이해가 가능하다.

setTimeout({
  console.log("시작2")
},0)

console.log("시작1")

  • setTimeout 함수가 callstack에 적재된 후, 해당 API를 처리하기위해 background에 적재되어 "시간지연"이 처리된다(logic처리가 아님).

  • 이 적재되는 과정에서 스레드(코드)가 non-blocking 되지않고, 해당 처리에 대한 동기처리가 아니기 때문에 이후 logic이 실행된다(console.log("시작1") 실행, 시작1 출력).

  • WebAPI 처리 후 여기에 해당되는 logic이 TaskQueue에 적재되고, 적재가 된 이후에 call stack에 함수가 없을때 logic을 call stack에 다시 적재한다.

  • call stack에 적재된 logic(console.log("시작2")를 실행, 출력한다.

이 과정에서 call stack이 비워져있는 것을 확인하는 주체가 event loop이다.

event loop는 setTimeout 뿐만 아니라, 특정 시점에서 동작할 수 있도록 비동기 처리를 지원하는 API에 대해 관여하는 역할을 한다.

이러한 event loop 처리가 있기 때문에 비동기 처리가 가능해진다.

3. 싱글스레드

다중스레드에서 발생하는 자원배분문제, 동시성문제를 해결하기 위해 싱글스레드로 요청을 처리한다.

javascript는 단일 스레드 환경에서 코드를 실행하고 명령들을 처리한다.

멀티스레드는 기본적으로 병렬처리를 위한 환경이며, 이 경우 node.js에서 다량의 트랜잭션을 처리할 때 동시성문제가 발생하게 된다.

이러한 문제를 해결하기 위해 javascript는 단일스레드 환경에서 처리하며, 단일 웹페이지 사이트의 javascript 코드들이 여러개 실행되는 것을 막는다.

  • 싱글스레드 환경에서 비동기 처리를 통해 트랜잭션 logic을 처리한다.
  • 처리 및 logic 구현 자체가 월등히 쉬워지고 가벼워진다.
  • 멀티스레드처럼 복잡하지 않고, 기본적으로 자원을 공유한다해도 이후 배분문제가 생길 수 있는 이슈를 사전에 방지한다.

4. 참조링크

Javascript 동작원리(싱글스레드 / eventloop)
https://chanyeong.com/blog/post/44
https://medium.com/@vdongbin/javascript-%EC%9E%91%EB%8F%99%EC%9B%90%EB%A6%AC-single-thread-event-loop-asynchronous-e47e07b24d1c

Javascript 동작의 구조적 원리
https://ooeunz.tistory.com/89

좋은 웹페이지 즐겨찾기