핵심 인사이트 (3줄 요약)

  1. 본질: 이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)은 프로세스와 스레드의 생성·실행·협력에서 핵심 흐름을 결정하는 개념으로, 시스템이 무엇을 먼저 관리하고 어떤 순서로 제어할지를 분명하게 만든다.
  2. 가치: 이 개념을 이해하면 자원 효율, 응답 시간, 안정성 사이의 균형을 더 정확하게 설명할 수 있고, 컨텍스트 스위칭 최소화를 위한 스레드 고정 (Thread Affinity/Pinning)로 이어지는 이유도 자연스럽게 파악된다.
  3. 판단 포인트: 코루틴 (Coroutine)과의 관계를 함께 봐야 이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)을 단순 정의가 아니라 실제 설계·운영 판단 기준으로 사용할 수 있다.

Ⅰ. 개요 및 필요성

1. 정의 및 특징

이벤트 루프(Event Loop)는 단일 스레드에서 이벤트 큐를 순회하며 콜백 함수를 디스패치하는 비동기 처리 아키텍처다. 멀티스레딩 없이 동시성을 달성하는 핵심 메커니즘이다.

비유: 식당 주방장이 혼자서 주문서를 하나씩 확인하고, 조리가 오래 걸리는 음식은 오븐에 맡겨놓고 다음 주문을 처리하는 방식과 같다.

┌─────────────────────────────────────────────────┐
│                 Event Loop                       │
│                                                   │
│   ┌─────────┐    ┌──────────┐    ┌──────────┐   │
│   │  Event   │───>│ Dispatch  │───>│ Callback │   │
│   │  Queue   │    │  & Exec  │    │ Complete │   │
│   └─────────┘    └──────────┘    └──────────┘   │
│        ^                               │          │
│        └───────────────────────────────┘          │
└─────────────────────────────────────────────────┘
┌─────────────────── Single Thread Timeline ───────────────────┐
│                                                              │
│  [A]──request──>[B]──request──>[A]──callback──>[C]──...     │
│   non-blocking   non-blocking   result                       │
│                                                              │
│  Legend: [A],[B],[C] = async operations                      │
└──────────────────────────────────────────────────────────────┘
  • 📢 섹션 요약 비유: 복잡한 창고에서 필요한 물건을 찾기 위해 먼저 구역과 표지판을 세우는 것과 같다.

Ⅱ. 아키텍처 및 핵심 원리

1. 논블로킹 I/O (Non-blocking I/O)

I/O 연산이 완료될 때까지 스레드를 차단하지 않고 즉시 반환하며, 작업 완료 시 콜백을 큐에 등록한다.

2. 이벤트 루프의 5단계 (Node.js 기준)

단계이름설명
1TimerssetTimeout, setInterval 만료된 콜백 실행
2Pending Callbacks이전 루프에서 지연된 I/O 콜백 실행
3Poll새로운 I/O 이벤트 수집 및 실행
4ChecksetImmediate 콜백 실행
5Closeclose 이벤트 콜백 실행
┌──────────────────────────────────────────────────────────┐
│                   Event Loop Phases                      │
│                                                          │
│   ┌────────┐  ┌────────┐  ┌──────┐  ┌───────┐  ┌─────┐│
│   │ Timers │─>│Pending │─>│ Poll │─>│ Check │─>│Close││
│   └────────┘  │Callback│  └──────┘  └───────┘  └─────┘│
│      ^        └────────┘     │                         │
│      └───────────────────────┘  (다시 반복)              │
│                                                          │
│   [Microtask Queue: Promise.then, process.nextTick]     │
│   > 각 페이즈 사이마다 우선 실행                          │
└──────────────────────────────────────────────────────────┘

3. 구현체별 특징

플랫폼엔진특징
Node.jslibuvC++ 기반, 파일 I/O + 네트워크 모두 비동기
Browser JSV8/SpiderMonkeyWeb API 사용, UI 렌더링과 병행
Python asyncioasync/await코루틴 기반, asyncio.run() 진입점
GogoroutineM:N 스케줄링, runtime에 이벤트 루프 내장

비유: 이벤트 루프의 페이즈는 우체부가 아침에 배달(Timers), 미처 못한 편지(Pending), 새 편지 수거(Poll), 등기 확인(Check), 마감(Close) 순으로 돌리는 일과와 같다.

  • 📢 섹션 요약 비유: 공장 컨베이어벨트가 어떤 순서로 부품을 받아 가공하고 내보내는지 설계도를 펼쳐 보는 것과 같다.

Ⅲ. 비교 및 연결

1. 콜백 기반 vs 프로미스 기반

┌────────────────── Callback Style ──────────────────┐
│                                                     │
│  readFile("data.txt", function(err, data) {        │
│      if (err) throw err;    // 콜백 지옥 가능       │
│      console.log(data);                             │
│  });                                                │
│                                                     │
└─────────────────────────────────────────────────────┘

┌────────────────── Promise Style ───────────────────┐
│                                                     │
│  readFile("data.txt")                               │
│      .then(data => console.log(data))               │
│      .catch(err => console.error(err));             │
│                                                     │
│  // async/await 변환                                 │
│  const data = await readFile("data.txt");           │
│                                                     │
└─────────────────────────────────────────────────────┘

2. 마이크로태스크와 매크로태스크

구분예시실행 시점
MicrotaskPromise.then, queueMicrotask현재 페이즈 종료 직후, 다음 페이즈 이전
MacrotasksetTimeout, setImmediate다음 이벤트 루프 틱(tick)
  • 📢 섹션 요약 비유: 비슷해 보이는 공구를 나란히 놓고 언제 망치를 쓰고 언제 드라이버를 써야 하는지 구분하는 것과 같다.

Ⅳ. 실무 적용 및 기술사 판단

1. 장점

  • 스레드 생성/컨텍스트 스위칭 오버헤드 없음
  • 메모리 사용량 적음 (단일 스레드)
  • 수만 개의 동시 연결 처리 가능 (C10K 문제 해결)
  • 동기 코드와 비슷한 제어 흐름으로 작성 가능

2. 한계: CPU 연산 집약적 작업

┌──────── CPU-Bound Blocking ────────┐
│                                     │
│  [Event Loop]──[Task A]────────────>│ BLOCKED!
│                   │                 │ (다른 이벤트 전부 지연)
│                   │  CPU 100%      │
│                   │  10초 소요     │
│                   ▼                 │
│              [완료]                  │
│  [Task B, C, D... 지연됨]          │
│                                     │
└─────────────────────────────────────┘

해결책: Worker Thread 분리, 클러스터 모드 (멀티프로세스), C++ Addon 오프로딩

  • 📢 섹션 요약 비유: 운전자가 도로 상황에 따라 기어와 브레이크를 다르게 선택하는 것처럼 조건별 판단이 중요하다.

Ⅴ. 기대효과 및 결론

이벤트 루프 기반 비동기 처리
├── 핵심 개념
│   ├── 단일 스레드 이벤트 구동 아키텍처
│   ├── 논블로킹 I/O
│   └── 콜백 큐 순회 및 디스패치
├── 이벤트 루프 페이즈
│   ├── Timers (setTimeout/setInterval)
│   ├── Pending Callbacks (지연된 I/O)
│   ├── Poll (새 이벤트 수집)
│   ├── Check (setImmediate)
│   └── Close (닫기 콜백)
├── 구현체
│   ├── libuv (Node.js)
│   ├── Browser Web API
│   ├── Python asyncio
│   └── Go runtime scheduler
├── 비동기 패턴
│   ├── Callback (콜백 지옥)
│   ├── Promise (then/catch/finally)
│   └── Async/Await (코루틴)
├── 장점
│   ├── 스레드 오버헤드 제거
│   ├── 적은 메모리 사용
│   └── C10K 문제 해결
└── 한계 및 해결책
    ├── CPU-bound 작업 시 블로킹
    ├── Worker Thread 분리
    └── 클러스터 (멀티프로세스)

약어Full Name
libuvLibrary for UV (Unified Virtualization)
I/OInput/Output
APIApplication Programming Interface
C10KClient 10,000 Problem

컴퓨터가 한 사람처럼 일할 때, 기다리지 않고 여러 일을 번갈아 하는 방법입니다. 주문이 들어오면 오븐에 넣고 다른 주문을 받는 식당 주방장과 같아요. 단, 계산이 아주 많이 필요한 일은 다른 도우미에게 맡겨야 합니다.

  • 📢 섹션 요약 비유: 도구의 장점만 외우는 것이 아니라 어디까지 믿고 어디서 보완해야 하는지 기억하는 정리 노트와 같다.

📌 관련 개념 맵

개념연결 포인트
고루틴 (Goroutine)현재 개념으로 들어오기 전에 함께 이해하면 경계가 선명해지는 기반 개념이다.
코루틴 (Coroutine)현재 개념이 등장하게 만든 직접적인 선행 흐름이다.
컨텍스트 스위칭 최소화를 위한 스레드 고정 (Thread Affinity/Pinning)현재 개념이 구현·세분화될 때 바로 연결되는 후속 개념이다.
CPU 친화성 (CPU Affinity)확장 학습이나 심화 비교로 이어지는 다음 단계의 키워드다.

📈 관련 키워드 및 발전 흐름도

[코루틴 (Coroutine)]
    │
    ▼
[이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)]
    │
    ├──▶ [컨텍스트 스위칭 최소화를 위한 스레드 고정 (Thread Affinity/Pinning)]
    └──▶ [CPU 친화성 (CPU Affinity)]

이 흐름도는 선행 개념에서 현재 개념으로 넘어온 뒤, 구현 세분화와 후속 확장으로 이어지는 학습 순서를 압축해 보여준다.

👶 어린이를 위한 3줄 비유 설명

  1. 이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)은 컴퓨터가 여러 일을 나눠서 처리하고 서로 기다리게 하는 약속이에요.
  2. 먼저 코루틴 (Coroutine)을 이해하면 이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)이 왜 필요한지 더 쉽게 보여요.
  3. 그래서 이벤트 루프 (Event Loop) 기반 비동기 처리 (Node.js)을 잘 알면 나중에 컨텍스트 스위칭 최소화를 위한 스레드 고정 (Thread Affinity/Pinning)도 훨씬 쉽게 배울 수 있어요.