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

박먼지·2023년 7월 18일
0
post-thumbnail

프론트엔드 면접 스터디에서 프로세스와 싱글 스레드, 멀티 스레드에 대해 공부해 오기로 했다.

그래서 공부하던 중에 자바스크립트가 왜 싱글 스레드 언어인지 궁금해졌다.

자바스크립트가 싱글 스레드 언어라는 것은 어렴풋이 알고 있었는데(어디서 주워들은 건 있음) 왜 싱글 스레드인지, 그리고 뭐가 좋은지에 대해서는 생각하지 않았다.

이번 기회에 알아보도록 하자!

개요

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

싱글 스레드는 스레드가 하나 있다는 뜻일 것 같은데, 그러면 스레드는 무엇일까?

스레드는 프로세스 내부에서 실행되는 흐름 단위라고 한다.

여기서 프로세스는 무엇일까?🤔

프로세스

프로그램을 실행하게 되면 프로그램이 CPU에 올라가서 동작하게 되는데 이것을 프로세스라고 한다.

작업 관리자에서도 확인할 수 있다.

프로그램과 프로세스의 차이

프로그램은 코드로 이루어진 정적인 파일(.exe로 끝나는 파일)을 의미한다.

나는 어떤 파일을 받았을 때 바탕화면에 아이콘으로 존재하는 상태로 이해했다.

그리고 이것을 더블 클릭하여 실행하게 되면 운영체제가 메모리(CPU)에 프로그램의 인스턴스를 할당하여 실행시키는데, 이렇게 할당된 동적인 상태의 작업 단위를 프로세스라고 한다.

즉 프로그램은 정적인 상태이고, 프로세스는 동적인 상태이다.

프로세스가 무엇인지 알겠는데, 왜 프로세스 내부에 스레드라는 것이 있을까? 🤔

스레드의 등장

기술이 발전하여 프로그램이 복잡해짐으로써, 하나의 프로세스로 하나의 프로그램을 실행하기에는 한계가 있었다.

하나의 프로세스만 사용하는 경우 먼저 하던 작업이 완료되기 전까지는 다음 작업을 처리할 수 없다.

그렇다고 프로세스를 여러 개 만들게 되면, 프로세스는 메모리를 차지하기 때문에 메모리의 비용이 증가하고, 프로세스 간의 교체(컨텍스트 스위칭)도 비효율적이다.

컨텍스트 스위칭?
정말 정말 간단히 말해서 하나의 프로세스에서 다른 프로세스로 교체하는 것을 말한다.

그래서 프로세스 내부에서 프로세스의 자원을 공유하는 스레드가 등장하게 되었다.

스레드는 프로세스의 자원을 공유하기 때문에 용량이 가볍고, 응답 시간도 훨씬 빠르다.

하나의 프로세스에는 하나의 메인 스레드를 갖고 있으며 스레드를 1개 이상을 가질 수도 있다.

스레드 하나로 프로그램을 처리하는 경우를 싱글 스레드라고 하고, 여러개로 처리하는 경우는 멀티 스레드라고 한다.

먼저 멀티 스레드에 대해서 알아보자!

멀티 프로세스와 멀티 스레드의 차이

멀티 프로세스는 간단하게 말하면 크롬 브라우저의 상단 탭들이고, 멀티 스레드는 현재 내가 보고있는 브라우저 창이라고 할 수 있다.

멀티 프로세스

만약 내가 탭을 여러개 띄워놓고 작업을 한다면, 한 탭에서 노래를 틀고 다른 탭에서 쇼핑을 하고, 또 다른 탭에서 파일을 다운로드 받는다면 다른 노래가 듣고 싶으면 노래 탭으로 가서 노래를 바꾸고, 다운로드가 끝났다면 파일 탭으로 가서 파일을 확인하는 등 작업을 전환하는 데 시간이 오래 걸릴 것이다.

이는 프로세스가 독립적으로 메모리(CPU)와 데이터(Code,Data,Stack,Heap)를 차지하고 있어서 다른 프로세스를 불러오게 되는 경우 CPU 메모리를 매번 초기화 하고, 불러올 데이터도 준비해야 하기 때문에 컨텍스트 스위칭이 오래 걸리기 때문이다.

하지만 프로세스가 독립적인 메모리 공간을 갖고있기 때문에 안정성을 확보할 수 있다는 장점이 있다.

크롬 브라우저에서 하나의 탭이 작동이 중지되어도 다른 탭은 문제 없이 이용이 가능한 것 처럼!

멀티 스레드

하나의 탭에서 노래를 듣고 쇼핑을 하고 파일을 다운로드 받는다면 일련의 과정을 한 곳에서 하기 때문에 효율적으로 작업을 처리할 수 있다.

이는 스레드가 하나의 프로세스 내에서 Stack과 Register를 제외한 데이터를 공유하기 때문에 교체할 데이터가 적어서 컨텍스트 스위치 비용이 낮아 교체가 빨리 이루어지기 때문이다!(작업이 거의 동시에 일어나는 것처럼 보임)

그리고 현재 창에서 내가 파일을 다운받다가 파일에 문제가 생긴 경우, 프로그램이 종료될 수 있다. 그런데 예외 처리나 에러 발생 시 새로운 스레드를 생성하는 등 적절한 처리를 한다면 프로그램 종료를 방지할 수 있다고 한다.😮

그리고 스레드는 같은 자원을 공유하기 때문에 여러 스레드가 동시에 같은 자원에 접근 할 위험이 있다. 그래서 데이터 접근을 제어하는 동기화작업을 해야 한다.🥲 동기화 작업은 병목 현상도 신경써야하고 여러모로 번거롭다고 한다..

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

스레드가 많으면 좋은거 아닌가?

싱글 스레드는 뭐가 좋은걸까? 🤔

싱글 스레드

싱글 스레드는 하나의 작업만 하기 때문에 컨텍스트 스위칭 작업을 하지 않고, 동기화를 신경쓰지 않아도 되기 때문에 비용이 절감된다.

따라서 자바스크립트 언어는 웹 페이지의 보조적인 기능을 수행하기 위해 프로그래머들이 가볍게 개발하기 위해 싱글 스레드 모델을 채택했다.

그러면 어떻게 멀티 스레드처럼 작동할까?

싱글 스레드는 먼저 하던 작업이 끝나기 전에는 다른 작업을 하지 못한다.

하지만 자바스크립트는 setTimeout이나 비동기 처리 등을 통해 멀티 스레드처럼 사용할 수 있다.

이것은 자바스크립트를 실행하는 런타임 환경인 브라우저, 혹은 Node.js가 멀티 스레드로 동작하기 때문에 비동기 작업을 수행할 수 있는 api 등을 사용해 멀티 스레드처럼 작동할 수 있는 것이다.

이를 자세하게 알아보자.

비동기 처리를 알아보기 위해서는 먼저 이벤트 루프에 대해 알아야 한다.

이벤트 루프

이벤트 루프는 런타임(browser, node.js)에서 가지고 있는 장치이며, 콜 스택과 콜백 큐(태스크 큐)를 감시하며 콜 스택이 비어있는 경우에는 콜백 큐에서 함수를 가져와 콜 스택에 넣어 주는 동작을 한다.

콜 스택(Call Stack) : 코드가 실행될 때 쌓이는 곳
콜백 큐(Callback Queue) : 비동기적으로 실행된 콜백함수가 보관되는 곳

만약 자바스크립트가 Web API에 있는 함수(ex:setTimeout)를 실행하게 되면, Web API가 이 함수의 타이머나 로드 등이 완료됐을 때 콜백 큐로 보내게 된다.
이벤트 루프는 콜 스택과 콜백 큐를 주시하다가 콜 스택이 비워지면 콜백 큐에 있는 함수들을 콜 스택으로 넘겨준다.

콜 스택이 비워지지 않으면 이벤트 루프가 동작하지 않아서 콜백 함수가 내가 생각한대로 동작할거라는 보장이 없다!

코드를 통해서 보자.


console.log('start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

console.log('end');

이것을 실행하게 되면

start
end
setTimeout

이렇게 나오게 된다!

~~ 추가 예정 ~~

정리

싱글 스레드로 작동하는데 필요할 때는 멀티 스레드처럼 작동한다는거 완전 무적 아닌가..?(뇌피셜) 자바스크립트 최고다👍

이번 기회에 프로세스와 스레드, 자바스크립트의 비동기 처리에 대해 좀 알게 된 것 같다.🥰

profile
개발괴발

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

글 잘 봤습니다, 감사합니다.

답글 달기