자바스크립트를 공부하다보면 정말 많이 들을 수 있는 말이 바로

 

자바스크립트는 싱글스레드로 동작한다

 

입니다.

 

여기서 드는 의문점 하나는, 왜 굳이 멀티스레드를 놔두고 싱글스레드로 동작할까 입니다.

 

누구나 멀티스레드가 싱글스레드보다 좋지 않냐고 쉽게 생각할 수 있는데, 왜 자바스크립트 개발자들은 여전히 싱글스레드를 고집하는 것일까에 대한 고민이 해당 포스팅으로 이어지게 되었습니다.

 


0. 싱글스레드인데 어떻게 여러 작업을 동시에 처리하지?

멀티스레드를 놔두고 싱글스레드로 동작하는 이유를 알아보기 전에, 진짜 자바스크립트가 싱글스레드인지, 또 어떻게 자바스크립트가 우리의 눈을 속이고 있을까에 대해서 먼저 알아보겠습니다.

 

0.0. 자바스크립트, 싱글스레드 맞아?

먼저 자바스크립트가 싱글스레드임을 확인하기 위해서 간단한 코드 하나를 가져왔습니다.

 

 

setTimeout(() => {console.log("코딩하는"}, 0); // 1
while(1) console.log("경제학도"); // 2
console.log("쏘코입니다."); // 3

 

해당 코드는 자바스크립트의 Run-To-Completion 특성에 의해서 "경제학도" 만 출력되고 나머지는 영원히 출력되지 않습니다.

Run-To-Completion을 간단히 설명하면 하나의 함수의 실행이 끝날 때 까지 다른 작업은 수행되지 않는다는 것이죠.

싱글스레드이기 때문에 가지는 특성이기도 합니다.

 

조금 더 자세하게 설명하면 해당 코드의 실행 순서는 2 3 1 입니다. (동작 순서에 대한 자세한 설명은 후술할 이벤트루프와 연관되어있습니다.)

하지만 2번 동작이 영원히 끝나지 않기 때문에 3과 1은 동작하지 않습니다.

 

 

0.1. 자바스크립트의 동시성 치트키 이벤트루프

이제 자바스크립트가 싱글스레드임을 확인했으니, 눈을 속이는 방법에 대해서 알아보겠습니다.

 

웹 브라우저가 어떻게 자바스크립트 코드를 실행시키는지에 대한 자세한 내용을 알지 못한다고 하더라도 일반적으로 사람들은 웹 페이지에서 자연스럽게 여러 동작이 동시에 일어난다고 인식합니다.

(싱글스레드임을 체감할 정도로 민감하다면.. 당신의 반응속도는.. 세계에서 손꼽을 정도일 지 모릅니다)

 

출처:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

 

위 사진은 이벤트루프가 어떻게 동작하는지에 대해서 간략하게 도식화한 사진입니다.

 

JavaScript 코드 내에서 비동기로 처리해야 하는 요소가 생긴다면 (callback이라든지, Promise라든지, async await이라든지, setTimeout이라든지...) JS는 자신이 그 요소를 처리하지 않고 Web API라는 친구에게 위임합니다.

그리고 나서 바로 다음 코드로 이동해서 작업을 수행하게 되는 것이죠.

 

Web API에서 처리된 내용은 Callback Queue(Task Queue)로 들어갑니다.

Callback Queue는 또 일반 Callback QueueAnimation Frames, Microtask Queue로 나뉘게 됩니다.

뒤로 갈수록 빠져나가는 우선순위가 더 높습니다.

 

어떻게 큐에서 요소들이 빠져나갈 수 있을까요?

여기서 바로 이벤트루프가 등장합니다!

이벤트루프는 JS엔진의 Call Stack을 지속적으로 바라보고 있다가, Call Stack이 비면 우선순위에 따라 각각의 Queue들에서 대기중인 요소들을 Call Stack으로 넣어줍니다.

 

출처:https://dev.to/lydiahallie/javascript-visualized-promises-async-await-5gke

 

여기서 한 가지 더 알고 가야 할 부분이, JavaScript가 싱글 스레드라는 것은 하나의 Call Stack을 가졌다는 의미와도 일맥상통합니다.

따라서 단 하나 존재하는 그 Call Stack이 비지 않았다면 Callback Queue에서 동작이 무한히 대기하게 되는 것이고, 그래서 위에서 두 번째 요소를 제외한 나머지 요소들이 동작하지 않은 것입니다!

 

이렇게 오래 걸릴 수 있는 동작들을 이벤트루프를 통해서 동시에 처리되는 것처럼 보이게 한다는 사실을 이제 잘 알 수 있겠죠?

 


1. 이벤트루프가 짱이네. 근데 멀티스레드 쓰면 되는거 아니야?

맞습니다. 

멀티스레드를 쓰면 자바스크립트의 동작을 WebAPI에게 굳이 위임하지 않아도 되고, 이벤트루프나 Callback Queue들도 필요가 없어지게 되겠죠.

 

하지만, 자바스크립트가 싱글스레드를 사용함으로써 얻는 이점은 바로 동시성 문제를 신경쓰지 않아도 된다는 것입니다.

그 예시로 iOS나 Android같이 멀티스레드 환경을 제공함에도 항상 주의사항이 따라붙는데, UI 스레드(메인 스레드) 이외의 다른 Worker 스레드에서는 UI 작업을 하지 말아야 한다는 것입니다.

 

사용자에게 있어서 화면이라는 자원에 여러 스레드가 동시에 접근하게 된다면 문제가 발생할 여지가 생기게 됩니다.

만약 같은 부분에 대해서 서로 다른 수정을 요구한다면, 우리가 생각한 대로 수정이 될 것이라는 보장을 하기 어려워지겠죠?!

 

이런 위험성을 차단하기 위한 목적과 함께, 멀티스레드로 얻을 수 있는 이득이 싱글스레드를 유지하는 것보다 크지 않기 때문에 JavaScript는 싱글스레드를 사용한다고 추측할 수 있겠습니다.

 

1.0. 주의!

그럼에도 자바스크립트에서 멀티스레드를 사용하기 위한 다양한 노력은 계속되고 있고, ES2017(ES8)에서 SharedArrayBuffer, 그리고 atomics 객체를 사용해서 메모리를 동시에 접근할 수 있게 하는 새로운 방법을 제시했습니다.

 

다만 해당 내용의 경우 2018년 초에 발생한 Intel CPU의 이슈문제 때문에 사용이 중단되기도 했고, 지금 시점에서 자유자재로 사용하기엔 어려운 부분이 있으니 꼭 필요한 경우에만 확인하고 사용하시는 것을 추천드립니다!

 

 

메모리 특강 ★ Mozilla 웹 기술 블로그

이 글은 3부작 시리즈의 첫번째 글입니다. 메모리 특강 만화로 소개하는 ArrayBuffer 와 SharedArrayBuffer Atomics 를 이용해서 SharedArrayBuffer 레이스 컨디션 피하기 ArrayBuffer 와 SharedArrayBuffer 가 JavaScript 에

hacks.mozilla.or.kr

 

A crash course in memory management – Mozilla Hacks - the Web developer blog

This is the first article in a 3-part series of code cartoons that explore SharedArrayBuffers in JavaScript and how they are used. To understand why ArrayBuffer and SharedArrayBuffer were added ...

hacks.mozilla.org

 

ES proposal: Shared memory and atomics

ES proposal: Shared memory and atomics (Ad, please don’t block) The ECMAScript proposal “Shared memory and atomics” by Lars T. Hansen has reached stage 4 this week and will be part of ECMAScript 2017. It introduces a new constructor SharedArrayBuffer

2ality.com

 


2. 참고자료

 

How JavaScript works: an overview of the engine, the runtime, and the call stack

As JavaScript is getting more and more popular, teams are leveraging its support on many levels in their stack - front-end, back-end…

blog.sessionstack.com

 

⭐️🎀 JavaScript Visualized: Promises & Async/Await

Ever had to deal with JS code that just... didn't run the way you expected it to? Maybe it seemed lik...

dev.to

 

[ 번역 ] 자바스크립트 시각화 : 비동기 처리

원문 : ⭐️🎀 JavaScript Visualized: Promises & Async/Await

velog.io

 

Event Loop (이벤트 루프)

이번 글은 Event Loop (이벤트 루프) 에 대해 정리해보려고 한다. Event Loop? Event Loop 출처 How JavaScript works: an overview of the engine, the runtime, and the call stack Event Loop는 MDN 문서로 검색하면 "큐의 다음 메시

velog.io

 

[JavaScript] setTimeout과 setInterval은 정확한 시간을 보장하지 않는다!

이번에도 스톱워치를 만들다가.. 말로만 듣던 setTimeout과 setInterval의 시간보장문제를 직접 맞닥뜨리게 되었습니다. 말로만 듣던걸 간단한 프로그램을 만들면서 직접 겪으니까 참 오묘하네요 ㅎ

ssocoit.tistory.com

 

자바스크립트 호출 스택(Call Stack) 이해하기

시작하기에 앞서자바스크립트를 심도 있게 이해하기 위해 "모든 자바스크립트 개발자가 알아야할 33가지 개념(https://github.com/yjs03057/33-js-concepts)"의 항목들과 링크되어있는 블로그 글들을 정리하

new93helloworld.tistory.com

 

코드스피츠85 2회-(1) 자바스크립트의 동시성

코드스피츠 85에서는 none blocking에 대한 이야기와자바스크립트를 짜는 근본적인 방법에 대한 고찰을 이야기해본다. 🌕🌑🌑 TL;DR 자바스크립트의 동시성 모델에 대해서 알아본다. 동시성이라는

feel5ny.github.io

 

자바스크립트는 왜 싱글 쓰레드일까? :: chanyeong

자바스크립트라는 언어는 싱글 쓰레드 언어라고 알려져있다. 보통 싱글 쓰레드라고 하면 한 번에 하나의 작업만 수행할 수 있다고 생각한다. 그렇다면 자바스크립트를 주로 사용하는 웹 사이트

chanyeong.com

네이버 D2 - 2018과 이후 JavaScript의 동향 - JavaScript(ECMAScript)

https://d2.naver.com/helloworld/7495331

반응형
  • 네이버 블로그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기