00_InboxOS - Context SwitchingContext Switching - 실제 전환 12단계

Context Switching - 실제 전환 12단계

03. PCB - 프로세스의 보관함 · 학습 지도 · 다음 → 05. 스케줄러와 상태 전이 - 다음 차례를 고르는 법

핵심

Context Switching은 실행 중인 A의 필요한 상태를 보존하고, Scheduler가 고른 B의 상태와 실행 환경을 복원하여 CPU가 B의 중단 지점부터 실행하게 만드는 과정이다. 아래 12단계는 Timer Interrupt로 A에서 B로 바뀌는 대표 흐름이다.

먼저 알아둘 정확성

CPU 아키텍처와 운영체제마다 자동 저장되는 Register, 저장 위치, 세부 순서는 다르다. 아래 흐름은 공통 원리를 이해하기 위한 모델이다.


시작 장면

현재 상황을 고정하자.

  • CPU 코어 0에서 Process A가 User Mode로 실행 중이다.
  • Process B는 Ready 상태로 자기 차례를 기다린다.
  • A에게 주어진 Time Quantum이 곧 끝난다.
  • A와 B는 서로 다른 주소 공간을 가진 Process다.
CPU 내부 현재 값 = A의 PC, SP, Registers, Flags
현재 주소 공간    = A의 주소 공간
Ready Queue       = B, C, ...

1단계: A가 평범하게 명령을 실행한다

CPU는 A의 PC가 가리키는 명령을 읽고 실행한다. Register에는 A의 계산 중간값이 들어 있다.

이때 A는 운영체제가 곧 자신을 멈출 것이라고 알 필요가 없다.


2단계: Timer Interrupt가 발생한다

운영체제가 미리 설정한 Hardware Timer가 신호를 보낸다. CPU는 현재 명령의 안전한 경계에서 Interrupt를 받아들인다.

Timer Interrupt의 중요한 목적은 운영체제가 CPU 제어권을 다시 얻는 것이다.

User Process A 실행
        ↓ Timer Interrupt
Kernel의 Interrupt 처리 코드로 이동

3단계: CPU가 최소한의 복귀 정보를 보존한다

Interrupt를 처리한 뒤 원래 실행으로 돌아갈 수 있도록 하드웨어가 최소한의 정보를 자동으로 보존할 수 있다.

대표적으로 다음과 같은 정보가 포함될 수 있다.

  • 돌아갈 명령 위치
  • 상태 Flags
  • 이전 실행 모드와 관련된 정보
  • 필요하면 Stack 전환에 필요한 정보

정확히 무엇을 하드웨어가 저장하는지는 CPU 종류마다 다르다.


4단계: User Mode에서 Kernel Mode로 들어간다

CPU는 권한이 높은 Kernel Mode에서 운영체제의 Interrupt Handler를 실행한다. 필요하면 Process A용 Kernel Stack을 사용한다.

여기서 중요한 사실은 “운영체제가 별도 CPU에서 구경하다가 개입하는 것”이 아니라는 점이다.

같은 CPU가 A의 사용자 코드를 실행하다가, 이제 운영체제의 Kernel 코드를 실행한다.


5단계: Kernel 진입 코드가 필요한 CPU 상태를 더 보존한다

하드웨어가 자동으로 저장하지 않은 Register 중, A를 정확히 재개하는 데 필요한 값들을 Kernel의 저수준 코드가 보존한다.

이 값은 개념적으로 A의 PCB에 속한 저장 영역이나 A의 Kernel Stack 등에 놓일 수 있다.

이제 B가 CPU Register를 덮어써도 A의 중요한 실행 상태는 안전하다.

A의 보존된 Context
├─ 다음 명령 위치
├─ Stack Pointer
├─ General Registers
├─ Flags
└─ 그 밖의 필요한 CPU 상태

6단계: Timer 사건을 처리하고 사용 시간을 계산한다

운영체제는 Timer Interrupt를 확인하고 필요한 처리를 한다.

  • A가 얼마 동안 CPU를 사용했는지 갱신
  • Time Quantum이 끝났는지 확인
  • 지금 더 높은 우선순위의 실행 대상이 있는지 확인
  • 다시 Scheduling할 필요가 있는지 표시

Interrupt가 왔다고 항상 다른 Process로 바꾸는 것은 아니다. A를 다시 선택할 수도 있다.


7단계: A의 상태를 Running에서 Ready로 바꾼다

이번 사건은 A가 입출력을 기다린 것이 아니라 Time Quantum을 다 쓴 경우다. A는 여전히 실행 가능하므로 Ready가 된다.

A: Running → Ready

A가 파일 읽기를 요청해서 멈춘 경우라면 Ready가 아니라 Waiting이 되어야 한다. 멈춘 이유에 따라 상태 전이가 달라진다.


8단계: Scheduler가 다음 실행 대상 B를 고른다

Scheduler는 Ready 상태의 후보를 보고 다음 실행 대상을 선택한다.

판단 기준에는 Scheduling 정책에 따라 다음이 쓰일 수 있다.

  • Queue의 순서
  • 우선순위
  • 지금까지 쓴 CPU 시간
  • 반응성을 높일 필요
  • CPU Core와의 친화성

여기서는 B가 선택되었다고 하자.


9단계: 낮은 수준의 실행 주체 전환을 한다

운영체제는 현재 실행 주체를 A에서 B로 바꾼다.

  • 현재 Task를 가리키는 Kernel 정보 변경
  • A의 Kernel 실행 Context 중 필요한 값 저장
  • B의 Kernel Stack과 저장된 Kernel Context로 전환
  • B의 상태를 Ready에서 Running으로 변경

이 구간을 Dispatcher가 실제 전환을 수행한다고 설명할 수 있다. Scheduler가 “B로 하자”고 고르면, Dispatcher가 그 결정을 실행에 옮긴다.


10단계: B의 Memory Context를 활성화한다

A와 B가 다른 Process라면 서로 다른 가상 주소 공간을 쓸 수 있다. 운영체제는 B의 주소 변환 기준, 예를 들면 Page Table과 관련된 CPU 설정을 활성화한다.

이때 TLB라는 주소 변환 Cache에 영향이 생길 수 있다. 최신 CPU의 식별자 기능 등으로 비용을 줄일 수도 있으므로, “Process가 바뀌면 TLB가 무조건 전부 비워진다”고 단정하면 안 된다.

같은 Process 안의 다른 Thread로 바꾸는 경우에는 보통 주소 공간을 공유하므로 이 단계의 부담이 더 작을 수 있다.


11단계: B의 저장된 CPU Context를 복원한다

B가 과거에 멈췄을 때 저장해 둔 값을 CPU 실행 상태로 되돌린다.

  • B의 Register 값
  • B의 Stack Pointer
  • B의 Flags
  • B가 이어서 실행할 명령 위치

이제 CPU 내부는 A의 실행 장면이 아니라 B의 실행 장면을 나타낸다.


12단계: Kernel에서 나가 B의 다음 명령을 실행한다

운영체제는 Interrupt 복귀와 같은 저수준 명령을 통해 적절한 권한 상태로 돌아간다. CPU는 B가 멈췄던 다음 명령부터 User Mode 실행을 계속한다.

B 입장에서는 긴 시간이 흘렀을 수 있지만, 논리적으로는 자기 코드의 다음 줄이 이어진다.

Switch 전 CPU
PC = A의 다음 명령
Registers = A의 값
Address Space = A

Switch 후 CPU
PC = B의 다음 명령
Registers = B의 값
Address Space = B

전체 순서를 한 그림으로 보기

sequenceDiagram
    participant A as Process A
    participant CPU as CPU와 Hardware
    participant K as OS Kernel
    participant S as Scheduler
    participant B as Process B

    A->>CPU: 사용자 명령 실행
    CPU-->>K: Timer Interrupt로 Kernel 진입
    K->>K: A의 필요한 Context 보존
    K->>K: A를 Running에서 Ready로 변경
    K->>S: 다음 실행 대상 요청
    S-->>K: B 선택
    K->>K: B의 Kernel 및 Memory Context 활성화
    K->>CPU: B의 Register와 PC 복원
    CPU->>B: B의 다음 사용자 명령 실행

멈추는 이유에 따라 무엇이 달라질까?

경우 1: Time Quantum 만료

A Running → A Ready
Scheduler가 다른 후보 선택 가능

A는 여전히 실행 가능하다. 단지 차례를 양보한다.

경우 2: Blocking I/O 요청

A Running → A Waiting
I/O 완료 전에는 A를 선택하면 안 됨

예를 들어 A가 아직 도착하지 않은 네트워크 데이터를 기다린다. CPU를 다시 줘도 할 일이 없으므로 Waiting Queue로 간다.

경우 3: B의 I/O 완료 Interrupt

B Waiting → B Ready
현재 A를 즉시 선점할지는 정책과 우선순위에 따라 결정

I/O 완료는 B를 실행 가능한 상태로 만들지만, 그 순간 무조건 A에서 B로 바뀐다는 뜻은 아니다.

경우 4: A가 종료

A Running → A Terminated
자원 정리 후 다른 Ready 대상 선택

경우 5: System Call 후 A가 바로 계속 실행

A가 Kernel에 요청했지만 기다릴 필요가 없고 Scheduler도 A를 그대로 실행하기로 하면, User Mode에서 Kernel Mode로 갔다가 다시 A로 돌아올 수 있다.

이것은 Mode Switch는 있지만 A에서 B로의 Process Context Switch는 없는 예다.


무엇을 저장하는 주체는 누구인가?

흔히 “OS가 Context를 저장한다”고 말하지만 실제로는 하드웨어와 Kernel 코드가 협력한다.

참여자대표 역할
Timer와 Interrupt HardwareKernel이 제어권을 얻을 사건 제공
CPU Hardware일부 복귀 정보 보존, 권한 전환, Handler 위치로 이동
Kernel 저수준 코드나머지 필요한 Register 보존·복원
Scheduler다음 실행 대상 선택
Dispatcher와 전환 코드Kernel Stack, 주소 공간, CPU Context 등을 실제 전환

자주 틀리는 압축 설명

틀리기 쉬운 말

Timer Interrupt가 발생하면 B의 PCB를 CPU에 올리고 A의 PCB를 메모리에 내린다.

이 표현은 PCB 자체와 CPU Context를 섞어서 말한다.

더 좋은 말

Timer Interrupt로 Kernel이 제어권을 얻는다. Kernel은 A를 재개하는 데 필요한 CPU Context를 보존하고 상태를 갱신한다. Scheduler가 B를 선택하면 B의 실행 환경과 저장된 Context를 복원하고 B의 중단 지점부터 실행한다.


스스로 20초 설명하기

아래 여섯 동사만 보고 전체 과정을 말해 보자.

Interrupt → 진입 → 저장 → 선택 → 복원 → 복귀

  1. Timer Interrupt로 Kernel이 제어권을 얻는다.
  2. 필요한 A Context를 저장한다.
  3. A의 상태를 Ready 등으로 바꾼다.
  4. Scheduler가 B를 선택한다.
  5. B의 Memory 및 CPU Context를 복원한다.
  6. B의 다음 명령으로 복귀한다.

다음 문서: 05. 스케줄러와 상태 전이 - 다음 차례를 고르는 법

Built with LogoFlowershow