frontEnd/javaScript

console.log("JavaScript 싱글 스레드");

Ama_grammer 2024. 9. 3. 22:40

 

자바스크립트언어는 싱글 스레드 언어인데 실제 사용시에는 멀티 스레드 처럼 사용을 한다.
어떻게 사용하나?

 

 

기술면접 예상 질문리스트에 답을 달던 중. 위의 질문을 보았고 다음과 같은 답변을 생각해냈다.

JavaScript 비동기 처리 동작 방식을 사용해 오래 걸리는 작업이 Call Stack으로 들어오면 Web API로 보내 별도로 처리하도록 한다.
Web API에서 처리가 끝난 작업들은 곧바로 Call Stack으로 들어가지 못하고 Task Queue에 순서대로 들어간다.
Event Loop가 Call Stack이 비어 있는 것을 계속 체크하고 Call Stack이 빈다면 Task Queue에서 가장 오래된 (가장 앞에 있는)작업을 Call Stack으로 보낸다.

 

널리 알려있듯 비동기 처리 동작 방식으로 JavaScript의 싱글 스레드의 단점을 줄일 수있다. 이렇게 넘어가려는데 답변에

"Web Worker" 라는 개념을 소개하는 부분이 있어 찾아보게 되었다.

"Web Worker" 가 무엇인지 알아보고, 비동기 처리 동작과 어떻게 다른지 비교해보자.


📌 Web Worker 

- Web Worker는 무엇인가?

사실 Web Worker 개념은 JavaScript의 자체 기능이 아닌 Web API의 일부 기능이다. 우선 Web Worker란 무엇일까?

웹 워커(Web Worker)는 스크립트 연산을 웹 어플리케이션의 주 실행 스레드와 분리된 별도의 백그라운드 스레드에서 실행할 수 있는 기술입니다. 웹 워커를 통해 무거운 작업을 분리된 스레드에서 처리하면 주 스레드(보통 UI 스레드)가 멈추거나 느려지지 않고 동작할 수 있습니다.
- 출처 : MDN

 

즉, JavaScript의 싱글스레드로 무거운 작업(예 : 이미지 관련 동작, 게임, 크기가 큰 반복문 등 )을 실행하면 본 화면이 멈추고 작업이 끝나고 나서야 정상적으로 application 이 동작하는데, 이것을 보이는 화면과 별도의 백그라운드 스레드(서브 스레드)에서 처리하게 함으로 메인 스레드에서 사용자의 경험을 향상시키는 것이다.

Web의 측면에서는 실제로 Web은 멀티스레드로 동작하기 때문에 멀티 스레드로 동작한다. 하지만, JavaScript의 측면에서는 싱글스레드 기반인 JavaScript의 본질은 변하지 않기 때문에 마치 멀티스레드로 동작하는 것 처럼 보인다.

 

- Web Worker 사용시 주의사항

Web Worker는 정말 필요로 할 때만 사용을 해야한다.

왜냐하면 백그라운드 스레드를 사용하면서 메모리 자원을 더 차지하게 되기 때문이다. 

정말 복잡한 작업 처리가 필요한 경우는 당연히 스레드가 많을 수록 처리 속도가 빠르기 때문에 속도 측면에서는 우수하다. 하지만, 스레드를 추가로 쓰는 것은 메모리를 더 차지하게 되기 때문에 싱글 스레드로 충분히 처리 가능한 Task를 멀티 스레드로 처리 하는 경우는 메모리를 낭비하는 행위인 것이다. 또한 Context Switching 이 잦게 발생하면서 오버헤드 비용이 발생할 수있는데, 그렇게 되면 성능 문제 또한 발생할 수 있다.

Context Switching : CPU 코어에서 실행중이던 프로세스의 스레드가 다른 프로세스의 스레드로 교체되는 것.


⭐️ 비동기 방식

- 비동기 방식란?

비동기 방식은 JavaScript에서 싱글 스레드의 단점으로 발생하는 한계를 마치 멀티 스레드처럼 동작할 수 있게 해줌으로 일정 범위까지 해결해주는 처리방식이다.

비동기(Asynchronous)라는 용어는 둘 이상의 객체 또는 이벤트가 동시에 존재하지 않거나 발생하지 않는 경우(또는 이전 객체 또는 이벤트가 완료될 때까지 기다리지 않고 발생하는 여러 관련 작업)를 말합니다. 컴퓨팅에서 "비동기"라는 단어는 두 가지 주요 맥락에서 사용됩니다.
- 출처 : MDN

 

위에서 말했듯 JavaScript는 싱글 스레드 기반 언어이기 때문에, 한 번에 하나의 Task만을 실행시킬 수 있다. 

단순한 코드에서는 한 번에 하나의 Task만을 실행시키는 것은 문제가 없지만 무거운 작업을 하는 경우는 말이 달라진다.

그런 상황에서 JavaScript는 Promise, async/await, setTimeout과  같은 비동기 함수를 이용해 다음의 순서로 Task를 처리한다.

[출처] : https://tech.treebo.com/async-programming-in-javascript-vs-python-11fd3e3f1b33

  1. 오래 걸리는 작업이 Call Stack으로 들어옴
  2. Web API로 보내 별도로 처리
  3. Web API에서 처리가 끝난 작업들을 Task Queue에 보낸다.
  4. Event Loop가 Call Stack이 비어 있는 것을 계속 체크한다.
  5. Call Stack이 비었을 경우 Task Queue에서 가장 오래된(FIFO) 작업을 Call Stack으로 보낸다.
  6. Call Stack에 들어온 처리된 비동기 Task를 처리한다.

🤔 Web Worker와 비동기 방식(Asynchronous)

- 공통점

  1. 비동기 방식
    • 둘 다 JavaScript에서 비동기적으로 작업을 처리할 수 있게 해준다.
    • Main Thread가 특정 Task를 끝낼 때까지 기다리지 않고 다른 작업을 계속할 수 있다.
  2. Main Thread의 차단 방지
    • 비동기 방식과 Web Worker 모두 Main Thread의 차단을 방지하여 사용자 인터페이스(UI)의 반응성을 높이는 데 도움을 준다.
    • 비동기 방식은 이벤트 루프를 사용하고, Web Worker는 별도의 Thread에서 작업을 수행한다.
  3. 비동기적 작업 실행
    • 두 방식 모두 네트워크 요청, 타이머 기반 작업, 데이터 처리 등과 같은 비동기적 작업을 실행할 수 있도록 돕는다.

- 차이점 

특징 비동기 방식
(Promise, async/await, setTimeout)
Web Worker
스레드 수 싱글스레드 멀티스레드(웹페이지 측면)
작동 방식 Event Loop와 Callback Queue를 통해 비동기 작업을 처리 브라우저에서 제공하는 백그라운드 스레드
(독립된 스레드)에서 코드 실행
사용 사례 주로 네트워크 요청, 타이머,
간단한 비동기 작업 처리
CPU 집약적 작업(이미지 처리, 데이터 분석)과 같은 무거운 작업 처리
DOM 접근 메인 스레드에서 실행되므로 DOM 접근 가능 Worker는 독립된 환경에서 실행되므로 직접 DOM접근은 불가능해서 메인 스레드와 메시지를 주고 받음
통신방법 메인 스레드 내에서 코드 실행  메인 스레드와 백그라운드(서브) 스레드가
메시지(postMessage/onMessage)를 통해 통신
성능 메인 스레드에서 가벼운 작업을 비동기로 처리 메인 스레드를 차단하지 않고 무거운 작업을 백그라운드에서 처리
리소스 소비 메인 스레드 내에서 효율적으로 리소스를 사용 추가 스레드 생성으로 메모리 및 리소스 사용 증가
API의 출처 JavaScript 언어 자체에 내장된 기능 웹 브라우저가 제공하는 API
(브라우저에 따라 지원여부 다름)

🔥 배운점

자바스크립트는 객체지향, 인터프리터, 싱글스레드 라는 특징을 갖은 언어인데, 싱글스레드로 발생하는 단점을 해결하기 위해 비동기 방식을 통해 마치 멀티스레드인것 처럼 동작한다. 이는 자바스크립트를 배우면 가장 중요한 내용중 하나라, 최소한 들어는 봤을 정도로 익숙했다. 하지만, Web Worker는 자바스크립트의 기능이 아닌 웹 브라우저에서 제공하는 API여서 그런지 기술면접을 준비하며 처음 들어본 개념이었다. 두개의 방식 모두 JavaScript에서 비동기 처리를 위해 사용되는 개념이다. 또한 두 방식 모두 JavaScript 측면에서는 싱글스레드임은 변함이 없다. 하지만, Web Worker는 웹 브라우저가 제공하는 API이고, 웹은 동작할때 멀티스레드로 동작한다. Web Worker는 지원되는 웹 브라우저의 측면에서는 자바스크립트의 메인 스레드가 아닌 브라우저의 백그라운드 스레드에서 돌기 때문에 메인 스레드와 백그라운드 스레드 즉, 두개의 스레드를 활용해 비동기 처리를 하는 것이다.

처음 듣는 개념에 우선은 잊지 않게 사전적 정리를 진행했다. 모던 JavaScript Deep Dive 를 다 학습한 후에 비동기 처리부분을 비교 학습하면서 비동기와 Web Worker를 예제 코드를 찾아보며 추가정리를 진행해야겠다.

 

학습중인 내용으로 잘못된 내용이 있다면 꼭 고치도록 하겠습니다.

참고

https://developer.mozilla.org/ko/docs/Web/API/Web_Workers_API

 

Web Workers API - Web API | MDN

웹 워커(Web worker)는 스크립트 연산을 웹 어플리케이션의 주 실행 스레드와 분리된 별도의 백그라운드 스레드에서 실행할 수 있는 기술입니다. 웹 워커를 통해 무거운 작업을 분리된 스레드에서

developer.mozilla.org

https://all-dev-kang.tistory.com/entry/Web-worker-%EC%9B%B9%EC%9B%8C%EC%BB%A4-%EA%B0%84%EB%8B%A8-%EC%82%AC%EC%9A%A9%EA%B8%B0

 

[Web worker] 웹워커 간단 사용기

들어가며 이번 글은 web worker(이하 웹 워커)에서 postMessage에 대한 에러를 확인하고 이를 수정하는 방법론? 에 대한 글입니다. 이 글에선 웹 워커의 간단한 동작,worker와의 통신, react에서 사용할 때

all-dev-kang.tistory.com

https://samori.tistory.com/87

 

웹 워커(Web Worker)란? 언제 쓰는 걸까? feat.타이머

브라우저가 인식할 수 있는 몇 안되는 언어인 자바스크립트는 놀랍게도 싱글 스레드이다. 싱글 스레드가 뭔지 모른다면 이전글을 참조하길 바란다. https://samori.tistory.com/86 싱글스레드 vs 멀티스

samori.tistory.com

https://developer.mozilla.org/ko/docs/Glossary/Asynchronous