언어/자바스크립트

[Javascript]스레드, 프로세스, 블로킹, 논블로킹

youngble 2022. 3. 3. 00:45

자바스크립트 cs관련 설명이 머무 좋아서 일부내용을 퍼왔다
출처:

 

[JavaScript] 런타임 작동 방식, 비동기와 이벤트 루프 - 하나몬

⚡️ [JavaScript] 런타임 작동 방식, 비동기와 이벤트 루프 ❗️알아볼 키워드 자바스크립트란? 자바스크립트 V8 엔진이란? 자바스크립트 런타임이란? 자바스크립트 싱글 스레드 기반 프로그래밍

hanamon.kr


자바스크립트와 싱글 스레드

자바스크립트는 싱글 스레드 프로그래밍 언어이다.
👉 스레드란? (single thread = 한 가닥)

스레드의 사전적 의미는 한 가닥의 실이라는 뜻이다.
한 가지 작업을 실행하기 위해 순차적으로 실행한 코드를 실처럼 이어 놓았다고 해서 유래된 이름이다.
싱글 스레드란 하나의 프로그램에서 동시에 하나의 코드만 실행할 수 있다는 뜻이다.
싱글 스레드란 코드가 실행되서 끝난 지점과 다음 코드의 시작 지점이 연결된 형태이다.
각 스레드는 한 번에 하나의 작업만 수행할 수 있다.
Task A —> Task B —> Task C
각 작업은 순차적으로 실행된다. (다음 작업을 시작하기 전에 이전 작업을 완료해야한다.)
멀티 스레드를 지원하는 프로그래밍 언어는 여러 *코어를 사용하여 여러 작업을 동시에 완료할 수도 있다.
Thread 1 : Task A —> Task B
Thread 2 : Task C —> Task D
동시에 돌릴 수 있는 스레드 수는 컴퓨터에 있는 *코어 갯수로 제한된다.
그런데 자바스크립트는 싱글 스레드이다.
스레드
🍀 잠깐! 프로세스와 스레드 그리고 멀티 스레드

프로세스와 스레드를 같이 공부해보면 좋다.
프로세스란 운영 체제에서 실행 중인 하나의 애플리케이션을 프로세스라고 한다.
사용자가 애플리케이션을 실행하면(프로그램을 실행하면) 운영 체제로 부터 실행에 필요한 메모리를 할당 받아 애플리케이션의 코드를 실행한다.
이때 실행되는 애플리케이션을 프로세스라고 한다.
정리하면 프로그램(파일)을 마우스 더블 클릭으로 실행 시켰을 때, 이 실행 되고 있는 프로그램을 프로세스라고 한다.
프로그램은 다중 프로세스로 만들기도 한다.
스레드는 이러한 프로세스 안에서 한 가지 작업을 실행하기 위해 순차적으로 실행되는 하나의 흐름이다.
멀티 프로세스가 애플리케이션 단위 멀티 테스킹이라면 멀티 스레드는 애플리케이션 내부에서의 멀티 테스킹이다.
멀티 코어 환경에서 여러 개의 스레드가 동시에 수행된다.

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

어 싱글이야
자바스크립트는 전통적으로 단일 스레드이다.
코어가 여러 개 있어도 메인 스레드라고 하는 단일 스레드에서만 작업을 행할 수 있다.
이러한 싱글 스레드는 하나의 힙 영역과 하나의 콜 스택을 가진다.
그래서 자바스크립트는 한번에 하나의 콜 스택(call stack)만을 가진다.
하나의 콜 스택을 가진다는 의미는 한 번에 한 가지 일 밖에 못한다는 의미이다.
아래 예시 코드와 같이 앞에 일이 완료 될 때까지 다음 코드는 다른 일은 하지 못하고 기다려야해서 웹 사이트에서 다른일을 할 수 없게 된다.
이렇게 싱글 스레드는 일을 동기적으로 처리한다.
function SignThreadTest() {
  console.log(1);
  for( let i=0; i<10000; i++ ) {
    console.log('자바스크립트는 싱글 스레드 프로그래밍 언어이다.');
  }
  console.log(2);
}
// '자바스크립트는 싱글 스레드 프로그래밍 언어이다.'가 10,000번 실행이 완료 될 때까지
// 콘솔 창에 '3' 이 찍히는 것을 기다려야한다.
SignThreadTest();
🍀 잠깐! 힙이 뭘까? 콜 스택이 뭘까?

자바스크립트 V8 엔진에는 두 가지 주요 구성 요소가 있다.
힙은 변수와 객체의 메모리 할당에 사용되는 비정형 메모리이다.
여기에서 중요한 것은 콜 스택이다. (콜 스택이 하나 뿐이라는 것이 중요하다.)
콜 스택은 코드를 읽고 함수가 실행되는 순서를 기억하고 있다.
위에서 자바스크립트는 싱글 스레드 프로그래밍 언어이고 하나의 힙 영역과 하나의 콜 스택을 가진다고 했다.
하나의 콜 스택을 가진다는 의미는 한번에 한 가지 일 밖에 하지 못한다는 의미라고 했다.
함수를 실행하려면 스택의 가장 위에 해당 함수를 넣게되고 함수에서 리턴이 일어나면 스택의 가장 위쪽으로 함수를 꺼낸다.
V8 엔진에서 오류가 발생하면 스택 추척을 콘솔에 인쇄한다.
자바스크립트-V8-힙과스택
❗️자바스크립트 동기와 블로킹

싱글 스레드는 동기적으로 일을 처리한다. 웹 브라우저의 WebAPIs는 비동기적으로 일을 처리한다.
👉 동기는 뭐고 비동기는 뭘까?

동기(Synchronous)와 비동기(Asynchronous)에 대해 알아보자.
동기 방식은 서버에서 요청을 보냈을 때 응답이 돌아와야 다음 동작을 수행할 수 있다. 즉, A작업이 모두 진행 될 때까지 B작업은 대기해야한다.
비동기 방식은 반대로 요청을 보냈을 때 응답 상태와 상관없이 다음 동작을 수행할 수 있다. 즉, A 작업이 시작하면 동시에 B작업이 실행된다. A 작업은 결과값이 나오는 대로 출력된다.
동기와 비동기
👉 싱글 스레드는 블로킹을 만든다.

싱글 스레드는 동기적으로 처리되기 때문에 블로킹을 만든다.
동기적으로 AJAX 요청을 보내면 브라우저는 모든 응답이 완료될 때까지 멈춰있다.
동기적으로 실행되는 네트워크 요청이 콜 스택을 블로킹하여 브라우저는 다른 일을 할 수가 없다.
여기서 주의할 점은 ‘동기적으로 네트워크 요청을 보내면’ 그렇다는 것이지 웹 브라우저가 제공하는 API가 동기적으로 요청을 보낸다는 것이 아니다.
(위에서 V8에는 힙과 스택만 가진다고 했고, 웹 브라우저에서 제공하는 API를 이용해서 네트워크 요청을 한다고 했다.
그래서 결론은 웹 브라우저는 비동기적으로 네트워크 요청을 보낸다는 것이다.
아래에서 좀 더 자세히 알아보자.)
👉 블로킹이란?

블로킹이라는 것의 정확한 정의는 존재하지 않는다.
그저 느리게 동작되는 코드일 뿐이다.
느린 동작이 스택에 남아 있는 것을 보통 블로킹이라고 한다.
웹 브라우저에서 코드가 실행되는데 코드가 종료될 때까지 유저가 클릭을 해도 어떠한 반응을하지 않는 상태가 된다.
Call Stack(콜 스택)이 멈춘 상태, 이 상태를 블로킹 상태라고 한다.
❗️자바스크립트 비동기와 논 블로킹

동기적 처리의 문제점 때문에 브라우저는 AJAX 요청을 비동기적으로 실행한다.
👉 웹 브라우저의 Web APIs는 비동기로 처리한다.

앞에서 웹 브라우저에 Web APIs 에는 setTimeout, DOM, AJAX(HTTP 요청)이 있다고 했다.
그리고 이벤트 루프와 콜백 큐를 가지고 있다.
자바스크립트 자체는 비동기적으로 요청을 처리할 수 없다.
자바스크립트 런타임 안에 지원하는 API로 비동기로 요청을 처리할 수 있게 하는 것이다.
👉 비동기 콜백으로 싱글 스레드 프로그래밍 언어에서의 블로킹을 해결할 수 있다. → 논 블로킹

웹 브라우저와 Node.js에는 동기로 처리하는 블로킹 메소드가 거의 없다.
대부분 지원 메소드가 비동기 처리를 하게끔 만들어졌다.
그렇다면 웹 브라우저와 Node.js에서 요청을 비동기로 어떻게 처리할 수 있는 것일까?
이는 어떤 코드를 실행하면 결국 콜백을 받고 이걸 나중에 실행한다는 말이다.
자세하게 풀어서 아야기하면 함수 호출 시 당장 실행하는 것이 아니라(동기→블로킹) 일단 어느 곳에 쌓아놓고 동시에 요청을 처리하고(비동기→논 블로킹) 요청이 완료된 순서대 로처리(스택 이용) 한다는 말이다.