본문 바로가기

FrontEnd 공부/JS와 관련된 고찰

싱글스레드인 JS에서 비동기 처리는 어떻게 할까?(1)

자바스크립트는 싱글스레드 언어인 것은 프론트엔드를 공부하는 사용하는 사람이라면 한번쯤은 들어봤을 것이다.
왜 자바스크립트는 싱글스레드인 것이고 그렇다면 비동기는 어떻게 처리하는지에 대해 알아보자.

 

자바스크립트는 왜 싱글 스레드인 것일까?🧐

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

자바스크립트를 공부하기 시작할 때 부터 계속 들어왔기에 너무나 당연시 여겼고, 이에 한번도 궁금증을 가져본 적이 없었다.

OS 공부를 하다보면 가장 중요한 내용 중 하나가 싱글 스레드와 멀티 스레드의 차이이다.

분명 우리는 싱글 프로세스 보다 일을 처리하는 것이 멀티 프로세스가 더 효율적이며, 멀티 프로세스 보다 더 가벼운 특성으로 인해 멀티 스레드가 더 선호된다고 배운다. 현재 JAVA, C, C++과 같은 다른 언어들은 멀티 스레드로 지원이 되는데, 자바스크립트는 왜 싱글 스레드 언어인 것일까?

 

여러 글을 보고 공부 하면서 자바스크립트가 싱글 스레드인 이유를 판단한결과 아래와 같다.

  • 웹페이지의 동시성 문제 때문이다.
    멀티 스레드로 구현된 서비스에서는 이 동시성 문제에 대해 많이 신경쓴다고 한다. 자바스크립트는 멀티 스레드 환경에서 발생할 수 있는 복잡한 시나리오를 신경쓸 필요 없다.
    실제로 구글의 chrome 브라우저도 기존 웹 페이지에서 엄청난 동시성 문제를 일으킬 수 있다는 이유로 단일 웹 사이트 페이지의 자바스크립트 코드가 동시에 실행되는 것을 허용하지 않는다.

  •  자바스크립트는 웹페이지의 보조적인 기능을 수행하기 위해 브라우저에서 동작하는 경량 프로그래밍 언어를 도입하기로 결정하고 만들어진 언어가 자바스크립트이다. 웹사이트를 구현하던 개발자들에게 자바라는 언어는 다소 무겁고 어려운 언어였기 때문에, 브랜던 아이크라는 사람을 스카우트하여 ‘자바스크립트’가 탄생되었다. 왜 무겁고 어려운 언어라 생각했을까?  멀티 스레드 모델은 프로그래밍 난이도가 높다고 판단했기 때문이라 생각한다.

여기서 동시성이란 ?

동시성(Concurrent)는 실제 물리적으로 동시에 일어나는 것이 아니라, 흐름을 실행시키는 것은 하나(e.g. CPU 코어 혹은 쓰레드)지만 작은 타임 슬라이스(Time slice, Time quantum)단위로 다른 흐름을 돌아가면서 실행시켜서 동시에 일어나는 것 처럼 보이게 하는 방식이다. 논리적인 의미에 동시 실행으로 볼 수 있다.

 

그렇다면 멀티 스레드에서는 어떤 동시성 문제가 발생하는가?

하나의 스레드에 문제가 생기면, 이를 공유하고 있는 다른 스레드에도 문제가 발생할 수 있다는 문제점교착상태(deadlock)가 발생할 수 있다. 여러 개의 스레드가 공유된 자원에 접근 할 때 데이터의 신뢰성을 보장받을 수 없는 없어 동기화 작업 필요하다.

 

자바스크립트 싱글스레드 라면서요 !?!?

위에서 자바스크립트가 싱글 스레드인 이유를 알아보았다. 싱글 스레드는 하나의 순차적인 작업 방식인 동기식(synchronous)으로 동작이 된다.

console.log(10);
console.log("Haen");
console.log(true);

위와 같은 코드를 동작 시켰을 때, 출력결과는 아래와 같이 10, Haen, true가 순차적으로 나온 것을 확인 할 수 있다.

그렇다면 다음 코드를 보도록하자.

console.log(1);
setTimeout(()=>{
    console.log(2);
},5000);
console.log(3);

위의 코드를 실행시키면 동기방식을 사용하므로 1이 출력된 후 5초 뒤에 2가 출력되고, 그 뒤에 3이 순서대로 출력될 것이다.

결과는 아래와 같다.

 

이럴수가?! 1과 3이 출력된 후 5초뒤에 2가 출력되었다.

이게 무슨일인가? 분명 자바스크립트는 싱글 스레드인 것인데…. 마치 멀티 스레드의 동작 방식과 같다.

 

싱글 스레드의 단점

자바스크립트는 싱글 스레드이기에 하나의 콜스택 만을 가지고 있다. 이는 2개의 함수를 동시에 호출하는 것이 불가능하며 가장 큰 단점은, 순차적으로 작업을 처리하기에 하나의 작업에서 많은 시간이 걸리면 이는 다른 작업의 지연시간으로 이어 진다는 것이다.

 

예를 들자면

슬기는 배고파서 햄버거를 사러갔다. 가게직원은 오직 한명이며, 현재 5명의 손님이 대기중이다.
한명의 주문을 처리하기 위해서는 주문받는시간 1분, 햄버거 만드는 시간 8분, 제공시간 1분이 걸린다.
즉, 한명이 주문을 하면 10분 뒤에 메뉴를 받을 수 있다. 햄버거 가게의 직원은 오직 한 명 이기에, 햄버거를 만드는 시간동안 다른 사람의 주문을 받을 수 없다. 가게직원이 여러 명이었다면, 직원 A,B가 햄버거를 만드는 동안 직원 C가 주문을 받을 수 있고 처리시간도 빨라질 것이다. 그러나 슬기는 주문하기 위해서는 50분이라는 시간을 기다려야 된다…!

 

 위의 예시와 같이 현재 처리중인 태스크가 종료될 때 까지 다음에 실행 될 태스크는 블락킹(blocking)상태가 된다.

이러한 단점이 발생하기에 동기 방식이 아닌 비동기 방식을 지원하는 언어가 많다. 비동기 실행을 지원하는 대표적인 방법으로는 멀티스레드가 있지만, 싱글 스레드인 자바스크립트는 이런 동기 방식의 단점을 이벤트 루프를 통해 보완하고 있다.

이벤트 루프란 무엇일까?

이를 이해하기에는 우선 자바스크립트 엔진에 대해 알아볼 필요가 있다.

 

자바스크립트의 엔진

자바스크립트 엔진의 대표적인 것은 바로 Google의 V8 엔진이 있다. V8엔진은 chrome과 node.js 내부에서 사용이 된다.

자바스크립트의 엔진은 위와 같은 형태로 구성되어있으며, 대표적인 두 구성요소로는 메모리 힙(Memory Heap)콜 스택(Call Stack)이 존재하며, 이밖에도 이벤트루프, 콜백 큐를 가지고 있다.

  • 메모리 힙(Memory Heap)
    • 메모리가 할당이 발생하는 곳이다.
  • 콜 스택(Call Stack)
    • 코드가 실행될 때 stack frame이 존재하는 곳이다.

브라우저에는 자바스크립트에서 거의 모든 사용자가 사용 가능한 API가 존재한다.(setTimeout과 같은) 이러한 API는 엔진에서 지원해주는 것이 아니라, DOM, AJAX, setTimeout 등과 같은 브라우저에서 제공하는 Web API가 존재한다.

 

콜 스택(Call Stack)

자바스크립트는 싱글 스레드이므로 싱글 콜 스택이 존재한다. 따라서 한번에 하나의 작업만을 처리할 수 있다.

호출 스택은 기본적으로 프로그램에서 우리가 어디에 있는지 기록하는 데이터 구조로 함수로 들어가면 스택의 맨 위에 놓고, 함수에서 반환하면 스택의 맨 위에서부터 나온다.

 

자, 그러면 다시 본론으로 돌아와 어떻게 자바스크립트가 비동기를 지원하는지 보도록 하자.

이벤트 루프

앞에서 보았듯이 콜 스택 작업은 스택의 맨 위에 있는 명령이 무엇인지 확인하고 실행하는 것이다. 실행하는 데 추가 시간이 필요한 setTimeout()과 같은 명령이 있는 경우 콜 스택이 이를 팝하고 Web API로 보낸다. 이 웹 API들을 이벤트 루프가 관리해주면서 자바스크립트의 콜 스택에 넣어준다.

이벤트 루프는 마우스 클릭이나 키보드 입력과 같은 이벤트가 발생했는지 지속적으로 확인하여 호출 스택으로 보낼 수 있도록 하는 역할로 이벤트 루프를 한마디로 정의하면  Orchestra (지휘자)로 정의를 할 수가 있다.

 

Javascript에서 모든 명령어는 콜 스택에 저장된다.

setTimeout 스택에 도달하면 엔진은 이를 Web API 명령으로 보고 팝(pop)하여 Web API로 보낸다. Web API 실행이 완료되면 이벤트 루프가 콜백 큐에 넣는다. 엔진은 콜 스택이 비어 있는지 확인한 후, 비어 있으면 setTimeout 명령이 있는 콜백 큐을 확인한다.

콜백 큐는 이를 콜 스택으로 보내고 명령이 실행된다.

 

위와 같은 방식으로 자바스크립트는 비동기 방식을 지원하는 것이다.

다음번에는 자바스크립트가 비동기를 지원하는 방식으로는 어떤 것들이 있는지 알아보도록 하겠다.

 

질문이나 궁금하신점 또는 제가 잘못 알고있는 정보는 댓글 부탁드립니다😊

Reference

자바스크립트는 왜 싱글 스레드를 선택했을까? 프로세스, 스레드, 비동기, 동기, 자바스크립트 엔진, 이벤트루프

 

자바스크립트는 왜 싱글 스레드를 선택했을까? 프로세스, 스레드, 비동기, 동기, 자바스크립트

목차 프로세스와 스레드 프로세스 싱글 스레드와 멀티 스레드 자바스크립트는 왜 싱글 스레드를 선택했을까 동기 vs 비동기 동기 비동기 자바스크립트로 비동기 처리하는 방법 자바스크립트 엔

miracleground.tistory.com

Why doesn't JavaScript support multithreading? - GeeksforGeeks

 

Why doesn't JavaScript support multithreading? - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

자바스크립트 동시성 모델과 이벤트 루프

 

자바스크립트 동시성 모델과 이벤트 루프

자바스크립트 동시성 모델 자바스크립트는 이벤트 루프에 기반한 동시성(Concurrency) 모델이라는 것을 가지고 있습니다. 이 모델은 다른 C나 Java와 같은 언어가 실행되는 방식과 다릅니다. 본디 자

eine.tistory.com

JavaScript Event Loop

 

JavaScript Event Loop

자바스크립트는 V8 엔진을 사용하는 싱글 스레드(single-Thread)를 사용하는 프로그램으로 널리 알려져 있다. 자바스크립트는 싱글스레드 언어라서, 단점으로 콜스택이 한 개밖에 없다.

medium.com

What does it mean by Javascript is single threaded language

 

What does it mean by Javascript is single threaded language

If you have been using Javascript for a while then you may come across the phrase that it’s a single threaded language.

medium.com