일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- STATE
- 웅진씽크빅
- React Query
- 프론트엔드
- 상태 관리 라이브러리
- sucoding
- 리액트프로젝트
- 프론트엔드 개발
- 공식문서
- TypeScript
- tanstack query
- React
- 개발
- 스나이퍼팩토리
- Server State
- 유데미
- frontend
- 프로젝트캠프
- 수코딩
- Today
- Total
yunicornlab
JavaScript의 특징 - 싱글 스레드 언어 본문
자바스크립트의 특징으로, 싱글 스레드로 동작하는 언어라는 점이 있다!
이번엔 JavaScript를 왜 싱글 스레드 언어라고 하는 지에 대해 알아보자.
일단, 단어부터 이해해보자.
스레드란(Thread)?
스레드란 프로세스(작업의 단위) 내에서 실행되는 흐름의 작은 단위를 말한다.
하나의 프로세스는 무조건 하나 이상의 스레드를 가지며, 하나의 프로세스는 내부에 여러 개의 스레드가 포함될 수 있다.
우리가 흔히 말하는 "프로그램"은 컴퓨터에서 실행할 수 있는 코드 파일을 의미하고, 프로세스는 이 프로그램이 돌아가는 상태를 말한다.
즉, 실행 중인 프로그램을 프로세스라 하는데, 컴퓨터는 프로그램을 실행하게 되면 메모리와 CPU 자원을 할당받아 이용하게 된다.
지금은 한 번에 여러 프로그램을 사용할 수 있는 멀티태스킹 환경이 익숙하지만, 처음에는 하나의 프로세스로 처리했기 때문에 그런 편리함이 가능하지 않았다.
동시에 여러 작업을 실행할 수 있는 이런 편리함은, 스레드를 통해 이뤄진것이다! 스레드를 통해 시스템 성능이 최적화되고 응답성을 높일 수 있었다.
같은 프로세스 내의 스레드들은 코드나 메모리를 공유하기 때문에 통신이 더 빠르고 효율적이다.
스레드는 프로세스와 다르게 독립적인 메모리 공간이 필요하지 않기 때문에, 새로운 프로세스를 생성하는 것보다 새로운 스레드를 생성하는 것이 자원을 더 효율적으로 사용하게 된다.
싱글 스레드란 vs. 멀티 스레드란
이름에서도 뜻이 나온 거나 마찬가지인데,
싱글 스레드(Single Thread)는 하나의 프로세스 안에 단 하나의 스레드만 있는 경우를 말한다.
하나만 있기 때문에 이 스레드가 프로세스 내에서 모든 작업을 순차적으로 처리한다.
또한, 하나만 있기 때문에 구조가 단순하고 자원 공유나 동기화 문제가 발생하지 않는다.
멀티 스레드(Multi-Thread)는 하나의 프로세스 안에 여러 스레드가 동시에 실행되는 경우를 말한다.
싱글 스레드와는 다르게 여러 작업을 병렬로 동시에 처리할 수 있어서 성능이 향상되고, 메모리를 공유하기 때문에 자원을 효율적으로 사용할 수 있다.
하지만, 여러 개가 있기 때문에 프로그램이 복잡해질 수 있고 동기화 문제가 발생할 수 있다.
기본적인 모델로 싱글 스레드 언어와 멀티 스레드 언어를 구분할 수는 있지만, 대부분 멀티스레딩을 추가로 지원한다.
JavaScript는 싱글 스레드 언어이다.
JavaScript는 기본적으로 싱글 스레드로 동작한다. 콜 스택이 하나뿐이기 때문이다! (콜 스택에 대해서는 다음에 알아본당)
JavaScript는 하나의 스레드에서 모든 코드를 순차적으로 처리하는 싱글 스레드 언어이다.
이 스레드는 스택을 사용해서 함수를 호출하고 실행을 관리하며, 호출된 함수가 완료되면 스택에서 제거된다.
하지만 점차 브라우저에서 복잡한 기능이 요구되면서, 싱글 스레드의 한계를 극복하기 위해 발전해갔다.
특히, 자바스크립트는 이벤트 루프를 사용해 비동기 작업을 처리할 수 있게 되었다.
자세한 건, 이후 다른 게시글에서 따로 정리할 것이다.
JavaScript는 왜 싱글 스레드 언어로 만들어 졌을까?
1995년에 JavaScript를 만들게 된 당시, 간단히 브라우저에서 사용자와 상호작용할 수 있는 경량화된 언어를 필요로 했기 때문에 복잡한 병렬 처리가 필요하지 않았다.
그리고 DOM을 조작할 때, 여러 스레드가 동시에 접근하면 일관성이 깨질 수 있다. 그래서 싱글 스레드 모델로 이러한 위험이 없어지고, DOM 조작의 일관성을 보장할 수 있게 되었으며, 여러 스레드 간의 동기화 문제를 피할 수 있게 되었다.
만들어질 때의 환경을 고려하면 애초에 웹 브라우저와 컴퓨터 성능이 현재보다 훨씬 낮았기 때문에 싱글 스레드로 만들어진 것도 맞다.
그렇지만 자바스크립트가 싱글 스레드 모델이었기 때문에 단순하고 속도 측면에서 유리해 자바스크립트가 더 많이 채택되고 확산될 수 있었다.
JavaScript는 브라우저 엔진을 통해 비동기 작업이 가능하다.
브라우저는 멀티 스레드로 동작한다. 그래서 싱글 스레드의 한계에도 불구하고 JavaScript는 브라우저 엔진을 통해 비동기 작업을 처리할 수 있다. 특히 Web APIs와 Event Loop와 Callback Queue를 사용하는 방식이다.
브라우저는 HTML 파싱이나 DOM 조작 등을 처리하는 메인 스레드와 렌더링을 담당하는 렌더링 스레드, 타이머 스레드, 네트워크 스레드 등 여러 스레드가 존재하는 멀티 스레드 구조이다.
이때 이벤트 루프라는 것이 자바스크립트 엔진의 싱글 스레드와 브라우저의 여러 스레드 간의 조정자 역할을 하면서 비동기 작업을 가능하게 해준다. (더 자세한건 다음에 알아볼 것이다.)
Web Workers - JavaScript의 멀티 스레딩
자바스크립트가 기본적으로 싱글 스레드 언어이기는 하지만, 멀티 스레딩을 할 수 있다!
바로 Web Workers라는 것을 이용하면 된다.
Web Workers는 자바스크립트에서 멀티 스레드 프로그래밍을 가능하게 해주는 기능으로, 이걸 사용하면 브라우저 환경에서 백그라운드 작업을 수행할 수 있다.
웹 워커는 UI 업데이트와 같은 기능을 하고있는 메인 스레드의 작업을 방해하지 않고 자신만의 스레드 컨텍스트를 가지고 백그라운드로 실행되기 때문에, 메인 스레드의 성능을 저하시키지 않는다.
웹 워커는 별도로 설치할 필요도 없다. Chrome, Firefox, Safari, Edge와 같은 대부분의 브라우저에서 기본적으로 지원되기 때문이다.
웹 워커를 사용하려면 new Worker() 생성자로 로드만 하면 된다. 그리고 postMessage와 onmessage라는 이벤트 핸들러를 통해 데이터를 주고 받으면 된다.
worker.js
onmessage = function(event) {
console.log('Message from Main:', event.data);
postMessage('Hello, Main!');
};
main.js
const worker = new Worker('worker.js');
worker.onmessage = function(event) {
console.log('Message from Worker:', event.data);
};
worker.postMessage('Hello, Worker!');
비동기와 멀티 스레딩의 차이는?
비슷해보여서 헷갈렸지만, 둘은 다른 개념이다.
비동기는 싱글 스레드와 멀티 스레드 모두 해당될 수 있다. 멀티 스레딩은 비동기의 한 형태라고 보면 된다.
동기와 비동기는 "순서"에 관한 것이고, 싱글 스레드와 멀티 스레드는 "작업자"에 관한 것이라 생각하면 편하다.
이해를 위해 직접 예시를 만들어보았다.
싱글 스레드에서의 동기 처리와 비동기 처리
하나의 스레드, 즉 한 명의 작업자가 모든 작업을 블로킹(멈추지)되지 않기 위해 애쓰는 모습이다😎
멀티 스레드에서의 동기 처리와 비동기 처리
동기는 결국 순서에 관련된 것이라서, 작업자가 많은 멀티스레드여도 동기 처리는 하나의 작업이 끝날때까지 기다려야 한다.
딱 봐도 비효율적으로 보인다.
Plus 질문) 동기화 문제가 무엇일까?
동기화 문제는 여러 스레드가 동시에 공유 자원에 접근할 때 발생할 수 있는 문제다. 주요 유형을 간단히 알아보면 다음과 같다.
(1) 경쟁 상태 : 여러 스레드가 동일한 자원에 동시에 접근하고, 자원에 대한 접근 순서가 결과에 영향을 미칠 때 발생한다.
ex. 두 스레드가 같은 변수를 동시에 증가시키려고 할 때, 예상하지 못한 값이 저장될 수 있는 상황
(2) 교착 상태 : 두 개 이상의 스레드가 서로의 자원을 기다리면서 무한히 대기하는 상태로, 프로그램이 더 이상 진행되지 못하게 된다.
ex. 스레드 A는 자원 1을 소유하고 자원 2를 기다리는데, 스레드 B는 자원 2를 소유하고 자원 1을 기다리는 상황
(3) 기아 : 하나의 스레드가 필요한 자원을 얻지 못해서 무한히 대기하는 상태를 말한다.
ex. 우선순위가 낮은 스레드가 우선순위가 높은 스레드들에 의해 계속해서 자원이 차단되는 상황
(4) 라이브락 : 스레드가 교착 상태를 피하려고 반복적으로 상태를 변경하지만 여전히 진행되지 못하는 상태를 말한다. 교착 상태와 유사해보이지만, 스레드가 활성 상태를 유지한다는 점에서 다르다.
결론
자바스크립트는 콜 스택이 하나뿐이기 때문에 싱글 스레드 언어이다!
이 특징을 먼저 이해해야 비동기 작업을 수행하기 위한 Web API, Event Loop의 사용과 블로킹, 위에서 소개한 Web Worker 등의 개념을 더 자연스럽게 이해할 수 있다.
'Frontend > JavaScript' 카테고리의 다른 글
JavaScript의 핵심! 실행 컨텍스트 이해하기 (0) | 2024.08.07 |
---|---|
JavaScript의 특징 - 멀티 패러다임 언어 (2) | 2024.07.22 |
JavaScript의 특징 - 동적 타입 언어 (0) | 2024.07.17 |
JavaScript의 특징 - 인터프리터 언어 (0) | 2024.07.14 |
[JavaScript] 자바스크립트 sort() 함수 이해하고 사용하기 (0) | 2024.06.11 |