Single Thread와 Javascript
2025. 3. 31. 20:30
728x90
반응형

Thread

  • 프로세스 (Process) 내에서 실행되는 가장 작은 단위.
  • 운영체제에서 실행 중인 프로그램이 하나의 프로세스 (Process) 이며, 각 프로세스는 독립적인 메모리 공간을 가지고 있으며, 다른 프로세스와 메모리 공간을 공유하지 않습니다.
  • 하나의 프로세스는 여러 개의 쓰레드를 포함할 수 있으며, 각 쓰레드는 독립적으로 작업을 처리합니다. 쓰레드는 프로세스의 자원을 공유하지만, 실행 흐름이 독립적입니다. 쓰레드는 CPU에서 실행되는 코드의 흐름을 나타내며, 프로세스 내에서 병렬 처리를 가능하게 만듭니다.

Thread 특징

  • 경량성(Lightweight) : 쓰레드는 프로세스보다 자원을 적게 소모하며, 다른 쓰레드들과 자원을 공유합니다. 따라서, 쓰레드 간의 전환 비용이 적고 더 효율적으로 작업을 분배할 수 있습니다.
  • 동시성(Concurrency) : 여러 개의 쓰레드를 사용하면 여러 작업을 동시에 실행하는 것처럼 보입니다. 하지만 실제로 하나의 CPU에서 여러 쓰레드를 순차적으로 실행하여 동시성을 구현합니다. 
  • 병렬성(Parallelism) : 멀티코어 CPU에서는 여러 쓰레드가 동시에 실행될 수 있어 병렬성을 구현할 수 있습니다. 즉, 실제로 여러 작업을 동시에 실행할 수 있습니다.

Single thread

  • 싱글 쓰레드(Single Thread) 는 여러 작업을 동시에 처리하는 것이 아니라, 순차적으로 작업을 하나씩 처리하는 방식을 의미합니다. 이는 한 번에 하나의 작업만 처리할 수 있다는 의미입니다.
  • javascript는 기본적으로 싱글 쓰레드(Single Thread) 환경에서 실행되기 때문에, 한 번에 하나의 작업만 처리할 수 있습니다.
  • 그러나 비동기 프로그래밍을 통해, 이벤트 루프와 콜백, Promise, async/await 등의 방법을 사용하여 비동기 작업을 효율적으로 처리합니다. 자바스크립트는 내부적으로는 여러 작업을 순차적으로 처리하면서도 동시에 작업을 처리하는 것처럼 보이게 할 수 있습니다.

비동기 프로그래밍

  • 자바스크립트에서 비동기 작업은 호출 스택(Call Stack), 이벤트 루프(Event Loop), 콜백 큐(Callback Queue) 을 통해 관리됩니다.
    • 호출 스택 (Call Stack) : 현재 실행 중인 코드들의 함수들이 쌓이는 구조입니다. 자바스크립트는 싱글 쓰레드이므로, 한번에 한 번의 작업만 호출 스택에서 실행됩니다.
    • 이벤트 루프 (Event Loop) : 이벤트 루프는 호출 스택이 비어 있는지를 계속해서 확인하고, 비어 있으면 콜백 큐(Callback Queue)에 대기 중인 작업을 호출 스택으로 가져와 실행합니다.
    • 콜백 큐 (Callback Queue) : 비동기 작업이 끝나면 해당 작업의 콜백 함수는 콜백 큐에 쌓이게 됩니다. 호출 스택이 비어 있으면, 이벤트 루프가 이 큐에서 콜백을 호출 스택으로 옮깁니다.
console.log('Start');

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

console.log('End');

 /* 
1. 첫 번째 로그 실행 (console.log('Start'))
	코드가 실행되면, 첫 번째 console.log('Start')가 호출 스택에 쌓입니다.
	console.log('Start')가 실행되고, 화면에 Start가 출력됩니다.
    
2. setTimeout 호출
	setTimeout 함수가 호출됩니다. setTimeout은 비동기 함수이므로, 콜백 함수가 즉시 실행되지 않고, 타이머가 설정됩니다.
	setTimeout의 콜백 함수는 0초 후에 실행되도록 설정되어 있지만, 이 콜백은 콜백 큐로 보내집니다.
	즉, setTimeout의 콜백은 호출 스택에서 즉시 실행되지 않고, 이벤트 루프에 의해 나중에 실행됩니다.

3. 두 번째 로그 실행 (console.log('End'))
	console.log('End')가 호출 스택에 쌓여 실행됩니다.
	console.log('End')가 실행되면서, 화면에 End가 출력됩니다.

4. 타이머 완료 후 콜백 큐에 콜백 추가
	setTimeout의 타이머가 0초로 설정되어 있기 때문에 거의 즉시 타이머가 완료됩니다. 하지만, 비동기 작업이므로 setTimeout의 콜백 함수는 콜백 큐에 들어갑니다.
	이때 setTimeout의 콜백 함수는 콜백 큐에서 대기 중이 됩니다.

5. 이벤트 루프가 콜백 큐를 확인
	이벤트 루프가 호출 스택이 비어 있는지 확인합니다.
	호출 스택이 비어 있으므로, 이벤트 루프는 콜백 큐에서 setTimeout의 콜백 함수를 호출 스택으로 가져옵니다.

6. 콜백 함수 실행 (console.log('Inside setTimeout'))
	콜백 함수인 console.log('Inside setTimeout')가 호출 스택에 쌓입니다.
	console.log('Inside setTimeout')가 실행되며, 화면에 Inside setTimeout이 출력됩니다.
    */
  • setTimeout과 같은 비동기 함수는 콜백 함수가 콜백 큐에 들어가게 하고, 콜백은 호출 스택이 비어 있을 때 실행됩니다. 자바스크립트의 이벤트 루프는 호출 스택이 비어 있을 때만 콜백 큐에 있는 작업을 실행할 수 있도록 합니다.
  • 여러 개의 비동기 작업이 중첩되면 콜백 헬(Callback Hell)이라고 불리는 문제가 발생할 수 있습니다. 이는 코드가 깊고 복잡해지면서 가독성이 떨어지는 문제입니다. 
    • 콜백 헬(Callback Hell) 은 여러 개의 비동기 작업이 중첩되면서 코드의 들여쓰기가 깊어지고, 가독성이 떨어지며, 유지보수가 어려워지는 문제를 의미합니다. 이 문제는 특히 여러 비동기 작업이 순차적으로 실행되어야 할 때 발생합니다.
doSomething(function(result1) {
  doSomethingElse(result1, function(result2) {
    doAnotherThing(result2, function(result3) {
      doYetAnotherThing(result3, function(result4) {
        console.log(result4);
      });
    });
  });
});
  • 이를 해결하기 위해 등장한 기술은 프로미스(Promise) async/await입니다. 이들은 비동기 작업을 순차적이고 직관적으로 작성할 수 있게 도와줍니다.
    • 프로미스(Promise) 는 비동기 작업이 완료될 때까지 기다리는 방법을 명확하게 제공하며, 여러 비동기 작업을 체이닝(chaining)할 수 있도록 합니다. 이를 통해 콜백 헬을 해결할 수 있습니다. Promise는 비동기 작업이 끝나면 결과를 반환하고, 그 결과를 처리하는 `then()` 메서드를 제공합니다. 여러 `then()`을 체이닝하여 비동기 작업을 순차적으로 처리할 수 있습니다.
    • async/await비동기 코드를 동기 코드처럼 작성할 수 있도록 도와줍니다. then() 메서드를 체이닝하는 대신, 순차적으로 코드를 작성할 수 있어 코드가 훨씬 간결하고 직관적입니다.
      • async : 함수 앞에 async를 붙이면 해당 함수는 항상 Promise를 반환합니다.
      • await : await는 프로미스가 처리될 때까지 기다리도록 하며, await는 반드시 async 함수 안에서만 사용할 수 있습니다.
728x90
반응형

'javascript' 카테고리의 다른 글

알아두면 유용한 Regex 리스트와 match, matchAll  (0) 2025.04.16
Regex (정규표현식)  (1) 2025.04.10
Scope Closure Currying  (0) 2025.03.30