핵심 인사이트 (3줄 요약)
- 본질: 스케줄러 액티베이션 (Scheduler Activation)은 사용자 수준 스레드가 커널 스레드에 매핑되는 다대다 (M:N) 모델에서, 커널이 사용자 수준 스레드 라이브러리에게 스레드의 블로킹/언블로킹/선점 이벤트를 상향 호출 (Upcall)로 통보하는 메커니즘이다.
- 가치: 커널이 직접 개입하여 사용자 수준 스레드의 상태 변화를 알려주므로, 한 스레드의 I/O 블로킹이 다른 스레드의 실행을 방해하지 않으면서도 커널 스레드의 무거운 생성 비용을 회피할 수 있다.
- 융합: LWP (Lightweight Process)를 가상 CPU로 활용하고 스케줄러 액티베이션으로 커널-유저 간 협력을 실현하는 이 구조는, Go 언어의 고루틴 (Goroutine) 런타임 스케줄러와 Java의 가상 스레드 (Virtual Thread) 스케줄러의 근간이 되는 핵심 아키텍처이다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
- 개념: 스케줄러 액티베이션은 Anderson 등이 1991년에 제안한 기법으로, 운영체제 커널이 사용자 수준 스레드 라이브러리에게 스레드 관련 이벤트를 알리기 위해 업콜 (Upcall)이라는 콜백 메커니즘을 제공하는 시스템이다. 이 메커니즘에서 커널은 각 LWP (Lightweight Process)에 대해 스케줄러 액티베이션이라는 커널 객체를 할당하고, 스레드가 블로킹되거나 해제될 때 이를 통해 유저 라이브러리에 통지한다.
- 필요성: 다대일 (N:1) 사용자 수준 스레드 모델에서는 하나의 유저 스레드가 블로킹 시스템 콜을 호출하면 프로세스 전체가 멈추는 치명적 문제가 있다. 반면 일대일 (1:1) 커널 스레드 모델은 스레드 생성 비용이 무겁고 확장성에 한계가 있다. 다대다 (M:N) 모델은 양쪽의 장점을 결합하지만, 커널이 유저 스레드의 상태 변화를 알지 못하면 적절한 LWP 할당이 불가능하다. 스케줄러 액티베이션은 이 정보 격차를 해소하는 유일한 통신 채널이다.
- 💡 비유: 본사(커널)가 지사(유저 라이브러리)에 파견할 직원(LWP)의 수를 조절하려면, 현장에서 직원이 휴가(블로킹)를 가거나 복귀하는 상황을 실시간으로 보고받아야 한다. 스케줄러 액티베이션은 이 "현장 상황 보고서"를 본사로 전송하는 긴급 연락망과 같다.
- 등장 배경: 초기 다대다 모델 구현체(예: SunOS의 UI 스레드)에서는 유저 스레드가 블로킹 시스템 콜을 호출하면, 커널이 이를 감지하지 못해 해당 LWP를 통해 실행되던 다른 유저 스레드까지 함께 멈추는 현상이 발생했다. 이를 해결하기 위해 커널이 능동적으로 유저 라이브러리에 이벤트를 통보하는 업콜 기반의 스케줄러 액티베이션 기법이 고안되었다.
스케줄러 액티베이션이 등장하게 된 문제적 상황과 해결 방향을 시각화하면 다음과 같다.
┌──────────────────────────────────────────────────────────────────────┐
│ 스케줄러 액티베이션 이전: 다대다 모델의 치명적 블로킹 문제 │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ [사용자 공간 (User Space)] │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ UT-1 ─(블로킹 I/O 호출)──┐ │ │
│ │ UT-2 ─(실행 준비 완료) │ │ │
│ │ UT-3 ─(실행 준비 완료) │ │ │
│ │ ┌──────────────────┘ │ │
│ │ ▼ │ │
│ │ [유저 스레드 라이브러리] ← 커널로부터 아무 통보도 받지 못함! │ │
│ └─────────┬──────────────────────────────────────────────┘ │
│ ──────────┼───── Mode Boundary ──────────────────────────── │
│ ▼ │
│ [커널 공간 (Kernel Space)] │
│ ┌────────┴────────────────────────────────────────────────┐ │
│ │ LWP-1 ─(UT-1의 시스템 콜 처리 중, Block 상태) │ │
│ │ LWP-2 ─(유휴, 할당되지 않음) │ │
│ │ │ │
│ │ 문제: 커널은 유저 라이브러리에게 "UT-1이 막혔다"고 │ │
│ │ 알려주지 않으므로, UT-2, UT-3은 실행될 기회를 잃음! │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ 해결: 스케줄러 액티베이션 → 커널이 유저 라이브러리에게 │
│ "UT-1이 블로킹됨, 다른 UT를 LWP에 할당하라!"고 통보 │
└──────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 그림은 스케줄러 액티베이션이 도입되기 전 다대다 스레드 모델의 핵심 결함을 보여준다. 유저 스레드 UT-1이 블로킹 시스템 콜을 호출하면 커널은 LWP-1을 Wait 큐로 이동시킨다. 그러나 커널이 유저 라이브러리에게 이 사실을 통보하지 않으므로, 유저 라이브러리는 여전히 UT-1이 실행 중이라고 착각하고 UT-2, UT-3을 LWP에 할당하지 않는다. 결과적으로 UT-2와 UT-3은 실행 가능(Runnable) 상태임에도 CPU를 할당받지 못하는 자원 낭비가 발생한다. 스케줄러 액티베이션은 커널이 이벤트 발생 시 즉각적으로 유저 라이브러리에 업콜을 보내, 유저 스케줄러가 다른 UT를 남은 LWP에 즉시 재할당할 수 있도록 하는 통지 메커니즘이다.
- 📢 섹션 요약 비유: 버스 회사(커널)가 승객(유저 스레드)이 하차(블로킹)해도 정류장 관리자(유저 라이브러리)에게 연락을 안 해주면, 빈 버스(LWP)가 그대로 방치되어 다른 승객도 타지 못하는 것과 같습니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
구성 요소
| 요소명 | 역할 | 내부 동작 | 비유 |
|---|---|---|---|
| 스케줄러 액티베이션 객체 | 커널이 관리하는 LWP 당 하나의 통지 자료구조 | 스레드 상태 변화 이벤트를 큐에 저장하고 유저 라이브러리에 전달 | LWP에 부착된 현장 상황판 |
| 업콜 (Upcall) 핸들러 | 유저 라이브러리 내의 콜백 함수 | 커널이 업콜을 발생시키면 해당 핸들러가 LWP 위에서 실행되어 스레드 재스케줄링 수행 | 긴급 상황 수신반 |
| LWP (Lightweight Process) | 유저 스레드가 실행되는 가상 CPU | 커널이 스케줄링하는 최소 단위이며, 스케줄러 액티베이션과 1:1로 연결 | 유저 스레드가 탑승하는 버스 |
| 가상 프로세서 (Virtual Processor) | 유저 라이브러리가 인식하는 실행 자원 | LWP의 개수를 가상 프로세서 수로 관리하여 유저 스레드를 분배 | 운행 가능한 버스 대수 |
업콜 기반 동작 메커니즘
스케줄러 액티베이션의 핵심은 커널이 이벤트를 감지하고 유저 라이브러리에 제어권을 넘겨주는 업콜 (Upcall) 과정이다. 다음은 유저 스레드가 블로킹 시스템 콜을 호출했을 때의 전체 동작 흐름이다.
┌─────────────────────────────────────────────────────────────────────┐
│ 스케줄러 액티베이션 업콜 동작 흐름 (블로킹 시나리오) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. UT-A가 LWP-1 위에서 블로킹 시스템 콜(read) 호출 │
│ ┌─────────────────────────────────────────┐ │
│ │ [User Space] [Kernel Space] │ │
│ │ ┌──────────┐ │ │
│ │ UT-A ────────────▶│ 커널 │ │ │
│ │ (LWP-1 위 실행) │ read() │ │ │
│ │ │ 처리 │ │ │
│ │ └────┬─────┘ │ │
│ │ │ │ │
│ │ 2. 커널: "I/O 미완료, LWP-1을 Block" │ │
│ │ ┌────▼─────┐ │ │
│ │ │ LWP-1 │ │ │
│ │ │ Block! │ │ │
│ │ └────┬─────┘ │ │
│ │ │ │ │
│ │ 3. 커널이 업콜 발생! │ │ │
│ │ ┌──────────────────────┘ │ │
│ │ ▼ │ │
│ │ [업콜 핸들러 실행] (LWP-2 위에서) │ │
│ │ a. UT-A의 상태를 '대기'로 표시 │ │
│ │ b. 레디 큐에서 UT-B를 선택 │ │
│ │ c. UT-B를 LWP-2에 할당하여 실행 재개 │ │
│ │ │ │
│ │ 4. I/O 완료 시 → 다시 업콜! │ │
│ │ a. UT-A의 상태를 '레디'로 복원 │ │
│ │ b. 다음 가용 LWP에 UT-A 할당 │ │
│ └─────────────────────────────────────────┘ │
│ │
│ 핵심: 커널이 이벤트를 유저 라이브러리에 즉시 통보하여 │
│ 스레드 블로킹이 다른 스레드에 영향을 주지 않음 │
└─────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 흐름도는 스케줄러 액티베이션이 유저 스레드의 블로킹을 어떻게 투명하게 처리하는지를 단계별로 보여준다. 핵심은 3단계에서 커널이 LWP-1을 블로킹시키는 것으로 끝나지 않고, 유저 라이브러리에 업콜을 발생시켜 "UT-A가 막혔으니 다른 스레드를 이 LWP(또는 다른 LWP)에 올려"라고 지시한다는 점이다. 업콜 핸들러는 커널이 보장한 별도의 LWP(여기서는 LWP-2) 위에서 실행되므로, 블로킹된 LWP-1과 무관하게 안전하게 동작한다. I/O가 완료되면 커널이 다시 업콜을 보내 UT-A를 레디 상태로 복원하고 가용 LWP에 재할당한다. 이 양방향 통신 덕분에 유저 수준 스레드의 가벼움을 유지하면서 커널 수준의 블로킹 격리를 동시에 달성할 수 있다.
LWP 동적 할당과 회수
스케줄러 액티베이션은 LWP의 수를 고정하지 않고, 실행 가능한 유저 스레드의 수에 따라 동적으로 LWP를 할당하거나 회수한다. 유저 스레드가 모두 블로킹 상태이면 불필요한 LWP를 커널에 반환하여 자원을 절약하고, 새로운 유저 스레드가 레디 상태가 되면 추가 LWP를 요청하여 병렬성을 극대화한다.
- 📢 섹션 요약 비유: 식당(유저 라이브러리)의 주문이 밀릴 때는 임시 아르바이트생(LWP)을 추가 고용하고, 한산할 때는 다시 보내는 유연한 인력 관리 시스템과 같습니다.
Ⅲ. 융합 비교 및 다각도 분석
스레드 모델별 블로킹 처리 방식 비교
| 비교 항목 | 다대일 (N:1) 모델 | 일대일 (1:1) 모델 | 다대다 + 스케줄러 액티베이션 (M:N) | 실무 판단 포인트 |
|---|---|---|---|---|
| 블로킹 전파 | 1개 UT 블로킹 시 프로세스 전체 차단 | 해당 KLT만 차단, 나머지 정상 | 업콜로 UT 재할당, 다른 UT 정상 실행 | I/O 바운드 워크로드 비중 |
| 커널 개입 | 최소 (비용 낮음) | 매 스레드마다 개입 (비용 높음) | 이벤트 발생 시만 개입 (비용 중간) | 스레드 생성/교환 빈도 |
| 확장성 | 수백만 UT 가능 (메모리 적음) | 수천~수만 KLT 한계 (메모리 큼) | 수만 UT + 수십 KLT 조합 | 동시 접속자 수 규모 |
| 멀티코어 활용 | 단일 코어만 사용 | 모든 코어 활용 가능 | KLT 수만큼 코어 활용 | 병렬 연산 요구 여부 |
세 가지 스레드 모델이 블로킹 상황에 어떻게 반응하는지를 시각적으로 비교한다.
┌────────────────────────────────────────────────────────────────────────┐
│ 세 가지 스레드 모델의 블로킹 처리 비교 │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ [상황: UT-1이 블로킹 I/O 호출, UT-2는 실행 준비 완료] │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │
│ │ 다대일 (N:1) │ │ 일대일 (1:1) │ │ 다대다 + SA │ │
│ │ │ │ │ │ (Scheduler Act.)│ │
│ │ UT-1 ─(Block)──│ │ KLT-1──(Block) │ │ UT-1 ─(Block)── │ │
│ │ UT-2 ─(Block!) │ │ KLT-2── UT-2 ◀─│ │ UT-2 ──▶ LWP-2 │ │
│ │ ▲ │ │ 실행 가능! │ │ 업콜로 │ │
│ │ 전체 차단! │ │ │ │ 자동 재할당! │ │
│ │ │ │ KLT 생성 비용 │ │ │ │
│ │ 커널은 1개만 │ │ 무거움 │ │ LWP 동적 할당 │ │
│ │ 인식 │ │ │ │ 비용 최적화 │ │
│ └─────────────────┘ └─────────────────┘ └──────────────────┘ │
│ │
│ 평가: │
│ N:1 = 빠르지만 블로킹 치명적 │
│ 1:1 = 안전하지만 무거움 │
│ M:N+SA = 둘의 장점 결합 (가벼움 + 안전) │
└────────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 비교도는 세 가지 스레드 모델이 동일한 블로킹 상황에서 어떻게 다르게 동작하는지를 명확히 보여준다. 다대일 모델에서는 UT-1의 블로킹이 프로세스 전체를 멈추게 하여 UT-2도 실행 불가능해진다. 일대일 모델에서는 각 스레드가 독립적인 KLT에 매핑되므로 UT-2는 정상 실행되지만, 모든 UT에 대해 KLT를 생성해야 하므로 메모리와 커널 오버헤드가 크다. 스케줄러 액티베이션이 추가된 다대다 모델에서는 커널이 업콜을 통해 유저 라이브러리에 UT-1의 블로킹을 통보하고, 유저 라이브러리가 UT-2를 가용한 LWP에 재할당하여 블로킹의 영향을 완벽히 격리한다. 동시에 LWP를 필요한 만큼만 유지하여 자원 효율까지 확보한다.
과목 융합 관점
-
컴퓨터 아키텍처 (CA): 하드웨어 인터럽트가 커널에게 비동기 이벤트를 통보하는 것과 유사하게, 스케줄러 액티베이션의 업콜은 커널이 유저 라이브러리에게 소프트웨어적 인터럽트를 통보하는 메커니즘이다. 두 계층 모두 이벤트 구동 (Event-driven) 아키텍처의 핵심 원리를 공유한다.
-
소프트웨어 공학 (SE): 옵서버 (Observer) 패턴이나 콜백 (Callback) 기반 이벤트 버스 아키텍처와 동일한 설계 사상이다. 커널이 이벤트 발행자(Publisher)이고 유저 라이브러리가 구독자(Subscriber)인 퍼블리시-서브스크라이브 (Publish-Subscribe) 모델의 OS 레벨 구현이라 볼 수 있다.
-
📢 섹션 요약 비유: 세 가지 모델은 각각 "혼자 달리기(다대일)", "각자 자전거 타기(일대일)", "지하철 노선에 유연하게 배차하기(다대다+SA)"로 비유할 수 있으며, 가장 효율적인 것은 상황에 맞춰 차량(LWP)을 늘리고 줄이는 지하철 배차 시스템입니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오
-
시나리오 -- 고동시성 웹 서버의 스레드 풀 고갈: 한 이커머스 서버에서 할인 이벤트로 인해 순간적으로 10만 건의 요청이 유입되었고, 스레드 풀의 모든 커널 스레드가 외부 결제 API 응답 대기로 블로킹되어 신규 요청 처리가 불가능해진 상황.
- 판단: 일대일 (1:1) 모델의 한계다. 커널 스레드당 약 1~2MB의 스택 메모리가 소요되므로 10만 개의 KLT를 생성하는 것은 메모리 파괴를 유발한다. Go 언어의 고루틴이나 Java의 가상 스레드처럼 M:N 모델 + 스케줄러 액티베이션 방식을 채택하면, 수만 개의 유저 스레드를 소수의 커널 스레드(LWP)에 얹어 블로킹 시 자동으로 다른 유저 스레드로 교체하므로 자원 소모를 최소화하면서도 높은 동시성을 달성할 수 있다.
-
시나리오 -- LWP 과다 할당으로 인한 CPU 스케줄링 오버헤드: 다대다 모델에서 유저 라이브러리가 실행 가능한 유저 스레드 수만큼 무제한 LWP를 요청하여, 4코어 서버에 100개의 LWP가 생성되고 커널 스케줄러의 문맥 교환 오버헤드가 폭증한 상황.
- 판단: 스케줄러 액티베이션에서 LWP의 수는 물리 코어 수와 밀접하게 연관되어야 한다. 유저 라이브러리는 시스템의 코어 수를 조회하고, I/O 바운드 작업 비율에 따라 코어 수의 1~2배 수준으로 LWP 상한을 설정하는 스마트 할당 정책을 구현해야 한다. 무조건 많은 LWP를 요청하는 것은 오히려 커널 스케줄링 비용만 증가시키는 안티패턴이다.
스케줄러 액티베이션 기반 시스템의 성능 최적화를 위한 의사결정 흐름을 요약한다.
┌───────────────────────────────────────────────────────────────────────┐
│ 스케줄러 액티베이션 기반 시스템 최적화 의사결정 트리 │
├───────────────────────────────────────────────────────────────────────┤
│ │
│ [다중 작업 처리 아키텍처 설계] │
│ │ │
│ ▼ │
│ 동시 실행해야 할 논리 스레드 수가 코어 수를 크게 초과하는가? │
│ ├─ 예 ─────▶ [다대다 (M:N) + 스케줄러 액티베이션 채택] │
│ │ │ │
│ │ └─▶ LWP 수 = 코어 수 * (1 + I/O비율) │
│ │ │
│ └─ 아니오 (코어 수 이하) │
│ │ │
│ ▼ │
│ I/O 바운드 작업이 주를 이루는가? │
│ ├─ 예 ─────▶ [일대일 (1:1) + 비동기 I/O 결합] │
│ │ │ │
│ │ └─▶ 구현 단순성 우선 │
│ │ │
│ └─ 아니오 (CPU 연산 위주) │
│ │ │
│ ▼ │
│ [코어 수와 동일한 스레드 수 + Lock-free 병렬화] │
│ │
│ 핵심: M:N 모델의 효율은 LWP 수를 코어 수에 맞추는 데 있음 │
└───────────────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 의사결정 트리는 스레드 모델 선택의 기준을 워크로드 특성과 코어 수에 따라 명확히 구분한다. 동시에 수만 개 이상의 논리 스레드를 관리해야 하는 I/O 집약적 워크로드(예: 채팅 서버, 웹 서버)에서는 다대다 모델과 스케줄러 액티베이션의 조합이 최적이다. 핵심은 LWP의 수를 물리 코어 수에 맞추는 것이다. I/O 대기 중인 LWP가 많다면 코어 수보다 약간 더 할당하지만, CPU 연산이 주를 이루는 상황에서는 LWP를 코어 수 이상으로 늘리는 것은 커널 스케줄링 오버헤드만 증가시킨다.
도입 체크리스트
-
기술적: 사용 중인 언어 런타임의 스레드 모델이 1:1(Java 기본), M:N(Go 고루틴), N:1(초기 Node.js) 중 무엇인지 파악했는가? I/O 대기 중인 스레드가 실제 코어를 점유하지 않도록 런타임의 업콜/이벤트 루프 메커니즘이 정상 동작하는가?
-
운영·보안적: M:N 모델에서 한 유저 스레드의 자원(CPU 시간) 과소비가 다른 유저 스레드의 기아 (Starvation)를 유발하지 않도록 런타임 레벨의 공정 스케줄링(Fair Scheduling)이 적용되어 있는가?
-
📢 섹션 요약 비유: 지하철(시스템)은 승객(유저 스레드) 수에 맞춰 열차(LWP)를 무한정 늘리지 않고, 수용 인원과 선로 수(코어 수)를 고려해 최적의 배차 간격을 계산해야 하는 것과 같습니다.
Ⅴ. 기대효과 및 결론
정량/정성 기대효과
| 구분 | 일대일 (1:1) 커널 스레드 모델 | 다대다 + 스케줄러 액티베이션 | 개선 효과 |
|---|---|---|---|
| 정량 (동시 스레드 수) | 수천~수만 개 (메모리 제약) | 수십만~수백만 개 가능 | 동시 처리량 100배 이상 증가 |
| 정량 (메모리 소모) | 스레드당 1~2MB 스택 | 유저 스레드당 수 KB (동적 스택) | 메모리 소비 95% 이상 절감 |
| 정성 (블로킹 격리) | 커널이 자동 격리 | 업콜 기반 유저-커널 협력 격리 | 두 모델 모두 동등한 안정성 확보 |
미래 전망
- 언어 런타임 스케줄러의 고도화: Go의 GMP(Goroutine-Machine-Processor) 모델, Java의 Virtual Thread Carrier 스케줄러, Rust의 tokio 비동기 런타임 등 현대 언어들은 모두 스케줄러 액티베이션의 핵심 아이디어를 발전시켜 자체 런타임에 내장하고 있다. 커널 의존도를 최소화하면서도 블로킹을 투명하게 처리하는 하이브리드 스케줄링이 표준으로 자리 잡았다.
- 코어 수 폭증에 대한 대응: 서버 CPU 코어 수가 256개 이상으로 늘어나면서, LWP 수를 코어 수에 비례하여 늘리는 기존 정책도 한계에 직면하고 있다. Work-Stealing (작업 훔치기) 스케줄링과 결합하여 LWP 간의 부하 균형 (Load Balancing)을 자동화하는 지능형 스케줄러가 연구 중이다.
참고 표준
-
Anderson et al. (1991): "Scheduler Activations: Effective Kernel Support for the User-Level Management of Parallelism" -- 스케줄러 액티베이션의 원 논문.
-
POSIX Threads (pthreads): M:N 모델을 지원하는 초기 구현에서 스케줄러 액티베이션 개념이 활용됨.
-
📢 섹션 요약 비유: 우체부(커널)가 집주인(유저 라이브러리)에게 "당신 편지 도착했어요, 빈 우체통(LWP)에 다음 편지 넣으세요!"라고 알려주는 친절한 시스템이 바로 스케줄러 액티베이션입니다.
📌 관련 개념 맵 (Knowledge Graph)
| 개념 명칭 | 관계 및 시너지 설명 |
|---|---|
| LWP (Lightweight Process) | 스케줄러 액티베이션의 실행 매개체로, 유저 스레드가 실제로 CPU를 할당받기 위해 탑승해야 하는 가상 프로세서이다. |
| 상향 호출 (Upcall) | 스케줄러 액티베이션의 핵심 메커니즘으로, 커널이 유저 라이브러리에게 이벤트를 비동기적으로 통보하는 콜백 기법이다. |
| 사용자 수준 스레드 (User-level Thread) | 스케줄러 액티베이션의 수혜 대상으로, 커널의 개입 없이 가볍게 생성되면서도 블로킹 시 커널의 통지를 받아 안전하게 동작할 수 있게 된다. |
| 다대다 모델 (Many-to-Many Model) | 스케줄러 액티베이션이 필수적으로 요구되는 매핑 구조로, 다수의 유저 스레드와 다수의 커널 스레드(LWP)를 유연하게 연결한다. |
| 문맥 교환 (Context Switching) | 스케줄러 액티베이션 환경에서는 유저 스레드 간 교환은 라이브러리가, LWP 간 교환은 커널이 담당하는 이중 스위칭 구조를 형성한다. |
👶 어린이를 위한 3줄 비유 설명
- 스케줄러 액티베이션은 학교(커널)가 반장(유저 라이브러리)에게 "친구 한 명이 병원(블로킹)에 갔으니, 남은 친구들로 조를 다시 짜!"라고 연락해 주는 시스템이에요.
- 이 연락(업콜)이 있기 전에는 한 친구가 아프면 반 전체가 수업을 멈춰야 했지만, 이제는 즉시 다른 친구가 대신 공부할 수 있어요.
- 선생님(커널)이 몇 명의 조교(LWP)를 보낼지도 상황에 따라 늘렸다 줄였다 하면서 가장 효율적인 학급 운영을 도와준답니다!