핵심 인사이트 (3줄 요약)
- 본질: 두 수준 (Two-level) 모델은 다대다 (Many-to-Many) 모델의 자원 효율성과 일대일 (One-to-One) 모델의 즉각적인 응답성을 결합한 하이브리드 스레딩 (Threading) 아키텍처다.
- 가치: 수많은 사용자 스레드를 적은 수의 커널 스레드에 다중화(Multiplexing)하면서도, 실시간 (Real-time) 처리가 필요한 특정 스레드는 전용 커널 스레드에 영구적으로 바인딩하여 블로킹(Blocking)을 방지한다.
- 융합: 과거 IRIX나 솔라리스 (Solaris) 같은 상용 유닉스 (UNIX) 운영체제 (OS, Operating System)에서 주로 사용되었으나, 멀티코어 CPU (Central Processing Unit)의 보편화와 스케줄링 복잡성으로 인해 현대에는 일대일 모델로 대부분 대체되었으며, 그 철학은 Go 언어의 고루틴 (Goroutine) 등 런타임 스케줄러에 계승되었다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
- 개념: 두 수준 (Two-level) 모델은 다수의 사용자 스레드 (User Thread)를 그보다 적거나 같은 수의 커널 스레드 (Kernel Thread)에 동적으로 매핑하는 다대다 모델을 기본으로 하되, 특정 사용자 스레드에 대해서는 하나의 커널 스레드를 독점적으로 할당하는 일대일 매핑을 예외적으로 허용하는 스레드 관리 기법이다.
- 필요성: 시스템에 수천 개의 스레드가 생성될 때, 이를 모두 커널 스레드로 만들면 커널 (Kernel) 메모리 고갈과 문맥 교환 (Context Switching) 오버헤드가 극심해진다. 이를 해결하기 위해 다대다 모델이 등장했으나, 다대다 모델에서는 하나의 커널 스레드가 블로킹 시스템 호출 (Blocking System Call)을 수행하면 매핑된 다른 사용자 스레드들까지 대기해야 하는 한계가 존재했다. 실시간성 (Real-time)이 중요한 작업이나 반드시 독립적으로 실행되어야 하는 스레드들을 보호하기 위해서는, 다중화의 이점을 취하면서도 예외적인 독점 바인딩(Binding)을 지원하는 구조가 필수적이었다.
- 💡 비유: 일반 직원은 공용 법인 차량(다대다 매핑)을 필요할 때마다 배차받아 사용하지만, 긴급 출동을 해야 하는 구급 대원이나 임원에게는 전용 차량(일대일 바인딩)을 고정적으로 지급하는 차량 운영 시스템과 같다.
- 등장 배경: 초기 운영체제는 커널 스레드를 지원하지 않는 다대일 (Many-to-One) 모델에서 출발하여 일대일 (One-to-One) 모델로 발전했다. 그러나 1990년대 제한된 하드웨어 자원에서 스레드 생성 비용이 너무 컸기 때문에 자원 최적화를 위한 다대다 모델이 고안되었고, 다대다의 블로킹 문제를 보완하기 위해 두 수준 모델이 탄생하게 되었다.
다대다 모델의 한계와 두 수준 모델의 해결책을 시각화하면 다음과 같다. 일반적인 다중화 상황에서 발생하는 블로킹 전파(Blocking Propagation) 문제를 어떻게 우회하는지 보여준다.
┌─────────────────────────────────────────────────────────────────────┐
│ 다대다 (Many-to-Many) vs 두 수준 (Two-level) 모델 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ [다대다 모델의 한계] │
│ 사용자 영역: U1 U2 U3 (I/O 요청) │
│ │ │ │ │
│ 커널 영역: └───────┴───────▼ │
│ K1 (블로킹 상태) │
│ ⚠ K1이 블로킹되면 U1, U2도 실행될 수 없음! │
│ │
│ [두 수준 모델의 해결책] │
│ 사용자 영역: U1 U2 U3 (일반) | U4 (실시간/중요) │
│ │ │ │ | │ │
│ LWP (중간): └───┬───┴───┬───┘ | │ (Bound) │
│ ▼ ▼ | ▼ │
│ 커널 영역: K1 K2 | K3 (전용 커널 스레드) │
│ │
│ ✅ U3가 K2를 블로킹해도, U4는 K3를 통해 독립적으로 실행 보장! │
└─────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 도식은 두 스레드 모델의 결정적인 구조적 차이를 보여준다. 다대다 모델에서는 여러 사용자 스레드 (User Thread)가 적은 수의 커널 스레드 (Kernel Thread)를 공유하기 때문에, 하나의 커널 스레드가 입출력 (I/O, Input/Output) 대기 등으로 블로킹(Blocking)되면 묶여 있던 다른 스레드들의 실행 기회까지 박탈당하는 병목 현상이 발생한다. 두 수준 모델은 이를 해결하기 위해, 블로킹에 민감하거나 지연 시간이 짧아야 하는 스레드(U4)를 커널 스레드(K3)에 하드 바인딩(Hard Binding)한다. 따라서 K1이나 K2가 I/O 대기 상태에 빠지더라도, 전용 커널 스레드를 가진 U4는 시스템의 다른 상태 변화에 영향을 받지 않고 즉시 CPU (Central Processing Unit) 스케줄링 대상이 될 수 있다. 이는 자원 한계를 극복하면서도 서비스 품질 (QoS, Quality of Service)을 보장하는 우아한 타협안이다.
- 📢 섹션 요약 비유: 복잡한 고속도로 톨게이트에서 대부분의 차량은 일반 차로(다대다)에서 대기하며 통과하지만, 앰뷸런스와 같은 특수 차량을 위해 하이패스 전용 차선(일대일)을 별도로 운영하여 병목을 원천적으로 해결하는 것과 같습니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
구성 요소
| 요소명 | 역할 | 내부 동작 | 관련 기술 | 비유 |
|---|---|---|---|---|
| 사용자 스레드 (User Thread) | 애플리케이션 로직 실행 단위 | 사용자 공간 스레드 라이브러리에 의해 생성/관리 | Pthreads (POSIX Threads) | 개별 승객 |
| LWP (Lightweight Process) | 사용자 스레드와 커널 스레드를 연결하는 가상 프로세서 | 사용자 스레드를 다중화하여 커널에 전달 | 스케줄러 액티베이션 (Scheduler Activation) | 버스 또는 택시 |
| 커널 스레드 (Kernel Thread) | 실제 CPU에 스케줄링되는 커널 내부의 실행 단위 | 운영체제 커널에 의해 선점형 스케줄링됨 | OS (Operating System) Kernel Scheduler | 실제 고속도로를 달리는 차량 |
| 바운드 스레드 (Bound Thread) | 특정 커널 스레드에 1:1로 고정된 사용자 스레드 | LWP 풀(Pool)을 거치지 않고 직접 커널 스레드와 결합 | 일대일 (One-to-One) 매핑 | 지정석 탑승객 |
| 언바운드 스레드 (Unbound Thread) | 가용한 LWP에 동적으로 할당되는 스레드 | 실행 시점에 유휴 상태인 LWP 중 하나를 점유 | 다대다 (Many-to-Many) 매핑 | 자율 좌석제 탑승객 |
두 수준 모델의 핵심 아키텍처는 사용자 공간과 커널 공간 사이에 위치한 LWP (Lightweight Process)라는 중간 계층의 존재다. 이를 통해 동적 매핑과 정적 바인딩이 공존할 수 있다.
┌────────────────────────────────────────────────────────────────────────┐
│ 두 수준 모델의 상세 아키텍처 구조도 │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ [User Space] │
│ Application Process │
│ ┌─── Unbound Threads (동적 할당) ───┐ ┌ Bound Thread (고정) ┐ │
│ │ T1 T2 T3 T4 │ │ T5 │ │
│ └───│───────│───────│───────│─────┘ └─────────│───────────┘ │
│ └───────┴───┬───┴───────┘ │ │
│ =================│===============================│============= │
│ [LWP Layer] ▼ 동적 매핑 (M:N) ▼ 정적 매핑 (1:1) │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │LWP│ │LWP│ │LWP│ │
│ └───┘ └───┘ └───┘ │
│ │ │ │ │
│ =================│=======│=======================│============= │
│ [Kernel Space] ▼ ▼ ▼ │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │KT1│ │KT2│ │KT3│ │
│ └───┘ └───┘ └───┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ [ CPU Core 0 ] [ CPU Core 1 ] │
└────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 구조도는 두 수준 모델이 언바운드 스레드 (Unbound Thread)와 바운드 스레드 (Bound Thread)를 어떻게 차별적으로 취급하는지를 명확히 보여준다. 사용자 공간의 스레드 라이브러리는 다수의 언바운드 스레드 (T1~T4)를 소수의 LWP (Lightweight Process) 풀에 동적으로 스케줄링한다. 이때 LWP는 커널 스레드 (KT1, KT2)와 1:1로 결합되어 있어, 실질적으로 커널 스레드를 의미한다. 반면, 실시간 처리가 필요한 T5는 생성 시점부터 전용 LWP와 KT3에 영구적으로 바인딩 (Bound)된다. 따라서 T1~T4가 과도한 연산을 수행하거나 I/O 대기로 인해 KT1, KT2가 블로킹되더라도, T5는 독립적인 스케줄링 단위인 KT3를 통해 CPU Core 1에 즉각적으로 진입할 수 있다. 이는 문맥 교환 (Context Switching) 오버헤드를 사용자 공간으로 국한시키면서도 커널 수준의 병렬성을 부분적으로 보장하는 정교한 설계다.
심층 동작 원리: 스케줄러 액티베이션 (Scheduler Activation)
두 수준 모델에서 커널과 사용자 스레드 라이브러리 간의 통신은 매우 중요하다. 커널 스레드가 블로킹되었을 때, 사용자 공간 라이브러리가 이를 인지하지 못하면 가용한 사용자 스레드를 스케줄링할 수 없기 때문이다. 이를 해결하는 메커니즘이 **스케줄러 액티베이션 (Scheduler Activation)**이다.
① 블로킹 발생: 언바운드 사용자 스레드가 LWP를 통해 I/O 시스템 호출 (System Call)을 실행하여 커널 스레드가 블로킹된다. ② 업콜 (Upcall): 커널은 이 블로킹 이벤트를 사용자 공간의 스레드 라이브러리에 알리기 위해 새로운 가상 프로세서 (LWP)를 할당하고 '업콜 (Upcall)'이라는 비동기 신호를 보낸다. ③ 상태 저장: 스레드 라이브러리는 업콜 핸들러를 통해 블로킹된 스레드의 상태를 저장한다. ④ 재할당: 새로 제공된 LWP를 이용하여, 대기 큐에 있던 다른 실행 가능한 언바운드 스레드를 즉시 실행시킨다. ⑤ 블로킹 해제: I/O가 완료되면 커널은 다시 업콜을 보내어 원래 스레드가 실행 가능해졌음을 알린다.
- 📢 섹션 요약 비유: 중앙 통제실(커널)에서 현장 작업자(커널 스레드)가 자재 부족으로 작업을 멈추면(블로킹), 즉시 현장 감독관(스레드 라이브러리)에게 무전(업콜)을 쳐서 남는 작업자를 다른 임무에 신속하게 재배치하는 유기적인 협업 시스템과 같습니다.
Ⅲ. 융합 비교 및 다각도 분석
스레딩 모델 비교 매트릭스
| 비교 항목 | 일대일 (One-to-One) | 다대다 (Many-to-Many) | 두 수준 (Two-level) | 판단 포인트 |
|---|---|---|---|---|
| 매핑 방식 | 사용자 1 : 커널 1 | 사용자 M : 커널 N (M ≥ N) | 다대다 (M:N) + 일대일 (1:1) 혼합 | 구조적 유연성 |
| 생성 오버헤드 | 높음 (매번 커널 모드 진입) | 낮음 (사용자 공간에서 생성) | 중간 (설정에 따라 다름) | 스레드 생성 빈도 |
| 동시성 (Concurrency) | 우수 (완전한 병렬 실행) | 중간 (LWP 수에 종속) | 우수 (바운드 스레드 독립성) | 멀티코어 활용성 |
| 블로킹 영향 | 해당 스레드만 블로킹 | LWP 부족 시 전체 애플리케이션 지연 | 중요 스레드는 블로킹 면역 | I/O (Input/Output) 비율 |
| 구현 복잡도 | 상대적으로 낮음 | 매우 높음 (스케줄러 액티베이션 필요) | 가장 높음 (두 가지 모델 동시 관리) | 운영체제 유지보수성 |
두 수준 모델과 현대 주류인 일대일 모델의 성능 및 자원 소모 트레이드오프를 그래프로 비교해 보면, 스레드 개수가 증가할 때 커널 자원이 어떻게 고갈되는지 시각적으로 이해할 수 있다.
┌────────────────────────────────────────────────────────────────────────┐
│ 스레드 개수에 따른 커널 메모리 소모량 및 성능 비교 │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ 커널 메모리 소모량 │
│ ▲ │
│ │ / (One-to-One 모델) │
│ │ / │
│ │ / ← 스레드 증가에 비례하여 커널 자료구조 폭증 │
│ │ / │
│ │ / │
│ │ / ------------------------- (Two-level 모델) │
│ │ / / ← LWP 최대 개수 도달 시 소모량 유지 │
│ │ / / │
│ │ / / │
│ │ / / │
│ └─────────────────────────────────────────────▶ 사용자 스레드 수 │
│ │
│ 성능 분석 (Performance Impact): │
│ - One-to-One: 코어 수가 충분할 때 최고의 병렬성 제공, 단 수만 개의 │
│ 스레드 생성 시 TCB (Thread Control Block) 오버헤드로 OOM 위험. │
│ - Two-level: 커널 자원을 보호하면서 대규모 동시성을 지원하지만, │
│ 사용자 공간 스케줄러의 복잡성으로 인해 단일 스레드 성능은 다소 저하.│
└────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 그래프의 핵심은 스레드 개수가 임계점을 넘었을 때 두 모델의 자원 소비 패턴이 완전히 달라진다는 점이다. 일대일 (One-to-One) 모델은 사용자 스레드 하나당 커널 스레드 하나가 무조건 매핑되므로, 수만 개의 스레드를 생성하면 커널 메모리 내의 TCB (Thread Control Block) 공간이 선형적으로 폭증하여 시스템 전체가 메모리 부족 (OOM, Out of Memory) 상태에 빠질 위험이 커진다. 반면 두 수준 모델은 언바운드 스레드를 제한된 수의 LWP 풀에 다중화하므로, 일정 수 이상의 LWP가 할당된 이후에는 커널 메모리 소모가 평탄해진다 (Flatten). 따라서 제한된 하드웨어 자원을 가진 과거 유닉스 환경에서는 두 수준 모델이 대규모 네트워크 연결을 처리하는 서버 애플리케이션 설계에 필수적이었다. 하지만 멀티코어 환경이 보편화되고 메모리가 저렴해진 현대에는, 복잡한 사용자 스케줄러를 버리고 단순한 일대일 모델에 스레드 풀 (Thread Pool)을 결합하는 방식이 대세가 되었다.
- 📢 섹션 요약 비유: 모든 시민에게 전담 공무원을 배정하는 것(일대일)은 서비스는 좋지만 예산이 고갈되고, 소수의 공무원이 수많은 시민을 응대하되 VIP 전용 창구를 따로 두는 것(두 수준)은 예산을 아끼면서도 핵심 업무를 방어하는 행정 철학의 차이와 같습니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오
-
시나리오 — 레거시 유닉스 기반 대규모 DBMS 운영: 과거 Solaris 8 환경에서 수천 개의 클라이언트 연결을 처리하는 Oracle 데이터베이스 시스템을 운영할 때, 모든 커넥션을 일대일 스레드로 생성하면 커널 패닉이 발생했다. 아키텍트는 일반 쿼리 요청은 다대다 매핑을 사용하는 언바운드 스레드로 처리하여 커널 스레드 수를 제한하고, 백그라운드에서 동작하는 데이터베이스 로그 라이터(Log Writer)나 체크포인트(Checkpoint) 스레드는 바운드 스레드로 설정하여 디스크 I/O 병목 상황에서도 멈추지 않도록 설계해야 했다.
-
시나리오 — 현대 런타임 환경 (Go Goroutine)으로의 진화: 두 수준 모델의 철학은 운영체제 커널 계층에서는 사라졌으나, 언어 런타임 수준에서 부활했다. Go 언어의 고루틴 (Goroutine)은 수백만 개의 경량 사용자 스레드 (Goroutine)를 소수의 OS 스레드 (M)에 스케줄링하는 M:N 매핑 (다대다) 모델을 사용한다. 이때 특정 고루틴이 C 코드를 호출 (CGO)하거나 장기 블로킹이 예상될 때 런타임이 새로운 OS 스레드를 스폰하여 바인딩하는 메커니즘은 본질적으로 두 수준 모델의 스케줄러 액티베이션 (Scheduler Activation) 원리와 동일하다.
과거 상용 UNIX 환경에서 발생했던 교착 상태 (Deadlock) 안티패턴을 시각화하면, LWP 부족이 어떻게 시스템 전체를 정지시키는지 알 수 있다.
┌─────────────────────────────────────────────────────────────────────────┐
│ LWP 고갈 (LWP Exhaustion)에 의한 데드락 시나리오 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ [상황: LWP Pool 크기 = 3, 모두 Unbound 스레드 사용] │
│ │
│ 스레드 T1 ──▶ [LWP 1] ──▶ 파일 읽기 (I/O 대기 중) │
│ 스레드 T2 ──▶ [LWP 2] ──▶ 파일 읽기 (I/O 대기 중) │
│ 스레드 T3 ──▶ [LWP 3] ──▶ 뮤텍스 락(Lock) 획득 후 I/O 대기 중 │
│ │
│ 스레드 T4 (락을 해제해야 하는 스레드) │
│ └─▶ 남은 LWP가 없어 대기열(Ready Queue)에 방치됨! │
│ │
│ 결과: T4가 실행되지 못해 락을 풀지 못하고, T3는 영원히 대기함. │
│ => 시스템 전체 데드락 (System-wide Deadlock) 발생! │
│ │
│ [해결책 (두 수준 모델의 적용)] │
│ T4를 반드시 실행되어야 하는 중요 스레드로 지정하여, │
│ "Bound Thread"로 설정 → 전용 커널 스레드 할당. │
│ → LWP 풀 고갈과 무관하게 T4 실행 → 락 해제 → 데드락 회피! │
└─────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 시나리오는 동적 매핑 기반의 스레드 환경에서 발생할 수 있는 가장 치명적인 문제인 '자원 기아에 의한 교착 상태'를 보여준다. 제한된 개수의 LWP (Lightweight Process)가 모두 I/O 대기로 인해 블로킹된 상태에서, 정작 그 블로킹을 해제하기 위해 필수적으로 실행되어야 하는 스레드(T4)가 LWP를 할당받지 못해 무한 대기하는 상황이다. 만약 시스템이 순수한 다대다 (Many-to-Many) 모델이었다면 이 상태에서 스스로 복구할 방법이 없다. 그러나 두 수준 모델은 락 해제 스레드나 인터럽트 처리 스레드와 같이 논리적으로 우선순위가 높은 스레드를 처음부터 바운드 스레드 (Bound Thread)로 강제 지정할 수 있는 탈출구를 제공한다. 이를 통해 커널 자원을 보호하면서도 시스템 안정성을 확보할 수 있으며, 실무적으로는 동기화 객체를 다루는 코어 스레드에 반드시 바운딩 설정을 적용해야 함을 시사한다.
도입 체크리스트
- 기술적: 애플리케이션 내의 스레드 중 I/O 바운드 작업과 CPU 바운드 작업의 비율이 어떻게 되는가? 실시간 응답이 필수적인 스레드와 백그라운드 배치성 스레드가 명확히 구분 가능한가?
- 운영·보안적: 할당할 최대 LWP 개수가 시스템 전체의 커널 메모리 제한을 초과하지 않는지 프로비저닝되었는가? 중요 스레드에 바운드 속성을 부여할 때 우선순위 역전 (Priority Inversion) 현상이 발생하지 않는가?
안티패턴
-
과도한 바운드 스레드 생성: 개발자가 성능 저하를 우려하여 대부분의 스레드를 바운드 스레드로 설정하는 경우. 이는 본질적으로 일대일 모델과 다를 바 없어지며, 오히려 두 수준 모델을 유지하기 위한 사용자 스케줄러의 문맥 교환 오버헤드만 가중시키는 최악의 설계가 된다.
-
📢 섹션 요약 비유: 호텔에서 만실(LWP 고갈)을 핑계로 비상문 열쇠를 가진 직원(T4)마저 밖에서 대기하게 만들면 화재(데드락) 시 대응할 수 없으므로, 핵심 인력을 위한 전용 출입구(바운드 스레드)를 항상 확보해 두는 비상 관리 체계와 같습니다.
Ⅴ. 기대효과 및 결론
정량/정성 기대효과
| 구분 | 적용 전 (일대일 모델) | 적용 후 (두 수준 모델) | 개선 효과 |
|---|---|---|---|
| 정량 | 수만 개 스레드 생성 시 커널 OOM | LWP 수량 제어로 메모리 제한 | 커널 메모리 소모 최대 80% 이상 절감 |
| 정량 | I/O 블로킹 시 전체 지연 시간 증가 | 중요 스레드 전용 처리 | 실시간 처리 응답 지연 밀리초(ms) 단위 보장 |
| 정성 | 하드웨어 자원에 강하게 종속 | 스레드 라이브러리 레벨 최적화 | 다중 사용자 환경에서의 시스템 안정성 증대 |
미래 전망
- OS 레벨에서의 퇴장과 런타임으로의 전이: 현대 운영체제 (Linux, Windows)는 풍부한 메모리와 멀티코어 환경의 발전으로 복잡한 스케줄러 액티베이션 메커니즘을 버리고 순수 일대일 (One-to-One) NPTL (Native POSIX Thread Library) 방식을 채택했다.
- 가상화 및 컨테이너와 결합: 두 수준 모델의 "소수 자원 위로 다수 워크로드 다중화" 철학은 vCPU와 하이퍼바이저 (Hypervisor) 매핑, 또는 Node.js 이벤트 루프나 Go 언어 런타임과 같은 사용자 수준의 그린 스레드 (Green Thread) 아키텍처로 진화하여 여전히 핵심 원리로 작동하고 있다.
참고 표준
- POSIX.1c (Pthreads): POSIX (Portable Operating System Interface) 스레드 표준에서는 매핑 방식 (일대일, 다대다, 두 수준)을 명시적으로 강제하지 않고 각 OS의 구현에 위임했다.
- Solaris Threads: 두 수준 모델의 가장 대표적이고 모범적인 상용 구현체 (Solaris 8 및 이전 버전).
운영체제 설계 역사에서 두 수준 모델은 자원의 한계와 성능에 대한 요구가 정면충돌할 때, 소프트웨어 아키텍트들이 어떻게 중간 계층 (LWP)을 도입하여 두 마리 토끼를 잡았는지를 보여주는 훌륭한 사례다. 비록 현재 OS 커널 단에서는 주류에서 밀려났지만, 이 구조적 사고방식은 여전히 최신 백엔드 비동기 프레임워크와 비동기 I/O (Asynchronous I/O) 모델의 밑바탕에 흐르고 있다.
- 📢 섹션 요약 비유: 기술의 발전으로 집집마다 우물(일대일 모델)을 팔 수 있게 되어 과거의 마을 공용 펌프(두 수준 모델)는 사라졌지만, 수돗물을 효율적으로 분배하는 상수도 망(현대 런타임 스케줄러)의 기본 설계도로 그 정신이 영원히 살아 숨 쉬는 것과 같습니다.
📌 관련 개념 맵 (Knowledge Graph)
| 개념 명칭 | 관계 및 시너지 설명 |
|---|---|
| LWP (Lightweight Process) | 사용자 스레드와 커널 스레드를 이어주는 논리적 다리 역할을 하며 두 수준 모델의 핵심 다중화 단위가 된다. |
| 스케줄러 액티베이션 (Scheduler Activation) | 커널 스레드의 블로킹 상태를 사용자 공간 스레드 라이브러리에 비동기적으로 통지하여 다대다 모델의 병목을 해결한다. |
| 문맥 교환 (Context Switching) | 사용자 공간 내에서의 스위칭은 커널 모드 진입이 필요 없어 오버헤드가 작으며, 두 수준 모델의 주요 성능 이점이 된다. |
| Pthreads (POSIX Threads) | 유닉스 계열 운영체제에서 스레드를 생성하고 동기화하는 API 표준으로, 하위 구현으로 두 수준 모델을 추상화하여 제공했다. |
| 고루틴 (Goroutine) | Go 언어의 경량 스레드로, 두 수준 모델의 M:N 매핑과 유사하게 런타임 레벨에서 OS 스레드 위에 동적으로 스케줄링된다. |
| 그린 스레드 (Green Thread) | 커널 스레드의 지원 없이 사용자 공간 가상 머신이나 라이브러리에 의해 스케줄링되는 스레드로, 두 수준 모델의 언바운드 스레드와 철학을 공유한다. |
👶 어린이를 위한 3줄 비유 설명
- 놀이공원(컴퓨터)에 수천 명의 손님(사용자 스레드)이 왔지만, 탈 수 있는 범퍼카(커널 스레드)는 50대뿐이에요.
- 그래서 대부분의 손님은 줄을 서서 빈 범퍼카가 나오면 번갈아 타야 해요(다대다 매핑).
- 하지만 놀이공원 사장님(운영체제)은 응급 구조대원(중요 스레드)을 위해 절대 다른 사람이 타지 못하는 전용 범퍼카(일대일 바인딩)를 따로 빼놓았어요. 이게 바로 '두 수준 모델'이랍니다!