컨텍스트 스위칭 (Context Switching)
1. 개요
컨텍스트 스위칭(Context Switching)이란 운영체제가 현재 실행 중인 프로세스나 스레드의 상태를 저장하고, 다음에 실행할 프로세스나 스레드의 상태를 복원하여 CPU의 제어권을 전환하는 과정을 말합니다. 이는 단일 CPU 환경에서도 여러 프로그램이 동시에 실행되는 것처럼 보이게 하는 멀티태스킹(Multitasking)을 구현하는 핵심 메커니즘입니다.
2. 동작 원리와 과정
CPU가 프로세스를 교체할 때, 이전에 수행하던 지점으로 다시 돌아와 작업을 계속하기 위해서는 현재까지의 진행 상태를 어딘가에 기록해두어야 합니다. 이때 사용되는 저장 공간이 PCB(Process Control Block, 프로세스 제어 블록)입니다.
2.1 PCB (Process Control Block)의 구성
PCB는 운영체제가 프로세스를 관리하기 위해 필요한 모든 정보를 담고 있는 데이터 구조체입니다. 주요 구성 항목은 다음과 같습니다.
* PID (Process Identifier): 프로세스를 고유하게 식별하는 번호
* 프로세스 상태 (Process State): 생성, 준비, 실행, 대기, 종료 등의 현재 상태
* 프로그램 카운터 (Program Counter): 다음에 실행할 명령어의 주소
* CPU 레지스터 (CPU Registers): 누산기, 인덱스 레지스터 등 CPU 내부의 현재 값
* CPU 스케줄링 정보: 우선순위, 스케줄링 큐 포인터 등
* 메모리 관리 정보: 페이지 테이블, 세그먼트 테이블 등 메모리 할당 정보
* 입출력 상태 정보: 할당된 I/O 장치, 열려 있는 파일 목록 등
2.2 스위칭 단계 비교
컨텍스트 스위칭은 크게 '현재 상태 저장'과 '새로운 상태 복원'의 두 단계로 나뉩니다.
| 단계 |
수행 작업 |
상세 내용 |
| 상태 저장 (Save) |
Process A $\rightarrow$ PCB_A |
현재 CPU 레지스터 값, 프로그램 카운터 등을 PCB_A에 기록 |
| 상태 복원 (Restore) |
PCB_B $\rightarrow$ Process B |
PCB_B에 저장되어 있던 이전 상태 값을 CPU 레지스터로 로드 |
[그림: 컨텍스트 스위칭 흐름도 - Process A의 상태가 PCB_A에 저장되고, PCB_B의 상태가 CPU로 복원되어 Process B가 실행되는 과정의 다이어그램]
3. 스케줄러의 역할과 관계
컨텍스트 스위칭은 단독으로 일어나는 것이 아니라, 운영체제의 스케줄러(Scheduler)에 의해 결정됩니다.
- 스케줄러의 역할: 준비 큐(Ready Queue)에 대기 중인 여러 프로세스 중 어떤 프로세스에 CPU를 할당할지 결정하는 알고리즘을 수행합니다.
- 상호작용 과정:
- 스케줄러가 CPU를 사용할 다음 프로세스를 선택합니다.
- 디스패처(Dispatcher)가 선택된 프로세스에 CPU 제어권을 넘기기 위해 실제 컨텍스트 스위칭을 수행합니다.
- 이 과정에서 이전 프로세스의 컨텍스트는 저장되고, 선택된 프로세스의 컨텍스트가 복원됩니다.
4. 컨텍스트 스위칭의 발생 조건
멀티프로그래밍 환경에서 다음과 같은 상황이 발생할 때 컨텍스트 스위칭이 트리거됩니다.
- 인터럽트(Interrupt) 발생: 하드웨어 장치(키보드, 마우스, 디스크 등)가 CPU에 신호를 보내 즉각적인 처리가 필요할 때 발생합니다.
- 시스템 콜(System Call) 호출: 프로세스가 I/O 작업(파일 읽기/쓰기 등)을 요청하여 CPU를 사용할 수 없는 '대기(Waiting)' 상태로 전환될 때 발생합니다.
- 타임 슬라이스(Time Slice) 만료: 시분할 시스템(Time-sharing system)에서 각 프로세스에 할당된 최대 CPU 사용 시간(Quantum)이 종료되어 강제로 CPU를 반납해야 할 때 발생합니다.
5. 오버헤드와 성능 영향
컨텍스트 스위칭은 논리적으로는 필수적이지만, 물리적으로는 아무런 유용한 작업을 수행하지 않는 오버헤드(Overhead) 시간을 발생시킵니다.
- CPU 시간 낭비: PCB 저장 및 복원 과정 자체에 CPU 사이클이 소모됩니다.
- 캐시 플러시(Cache Flush): 프로세스가 바뀌면 기존 프로세스가 사용하던 L1, L2 캐시 메모리의 데이터가 무효화됩니다. 새로운 프로세스가 실행되면 다시 메모리에서 데이터를 읽어와 캐시를 채워야 하므로, 스위칭 직후에는 메모리 접근 속도가 일시적으로 저하되는 캐시 미스(Cache Miss) 현상이 빈번하게 발생합니다.
6. 프로세스 vs 스레드 컨텍스트 스위칭
프로세스 간 스위칭보다 스레드 간 스위칭이 훨씬 효율적입니다. 이는 메모리 공유 구조의 차이 때문입니다.
6.1 차이점 분석
- 프로세스 스위칭: 서로 독립된 메모리 공간(Code, Data, Heap, Stack)을 가지므로, 가상 메모리 주소 체계를 관리하는 페이지 테이블(Page Table)을 완전히 교체해야 하며 TLB(Translation Lookaside Buffer)를 비워야 합니다. 이때 프로세스의 상태는 PCB(Process Control Block)에 저장됩니다.
- 스레드 스위칭: 동일한 프로세스 내의 스레드들은 스택(Stack) 영역을 제외한 메모리 공간을 공유합니다. 따라서 메모리 맵을 교체할 필요가 없으며, TCB(Thread Control Block, 스레드 제어 블록)에 저장된 레지스터와 스택 포인터만 변경하면 되므로 매우 빠릅니다.
- TCB (Thread Control Block): 운영체제가 각 스레드를 관리하기 위해 사용하는 데이터 구조체로, 스레드 ID, 스택 포인터, 프로그램 카운터, 레지스터 상태 등 스레드 고유의 실행 문맥을 저장합니다.
6.2 비교 요약표
| 구분 |
프로세스 컨텍스트 스위칭 |
스레드 컨텍스트 스위칭 |
| 전환 대상 |
서로 다른 프로세스 간 |
동일 프로세스 내 스레드 간 |
| 메모리 공유 |
공유하지 않음 (독립적) |
공유함 (Stack 제외) |
| 교체 항목 |
PCB, 페이지 테이블, TLB 등 |
TCB, 레지스터 |
| 오버헤드 |
매우 높음 (캐시 플러시, TLB 초기화 발생) |
상대적으로 낮음 (메모리 맵 유지) |
| 속도 |
느림 |
빠름 |
7. 최적화 방안
운영체제와 하드웨어 제조사는 컨텍스트 스위칭 비용을 줄이기 위해 다양한 기법을 도입하고 있습니다.
- 하드웨어적 지원:
- 다중 레지스터 세트: CPU 내부에 여러 세트의 레지스터를 두어, 포인터만 변경함으로써 즉시 컨텍스트를 전환하는 방식입니다.
- ASID (Address Space Identifier): TLB에 프로세스 식별자를 함께 저장하여, 스위칭 시 TLB 전체를 비우지 않고도 유효한 항목을 구분해 사용할 수 있게 합니다.
- 소프트웨어적 지원:
- 효율적인 스케줄링 알고리즘: 불필요한 스위칭 횟수를 줄이기 위해 적절한 타임 슬라이스 길이를 설정하거나, 우선순위 기반의 정교한 스케줄링을 적용합니다.
- 경량 프로세스(LWP) 및 코루틴(Coroutine): 커널 수준이 아닌 사용자 수준에서 스위칭을 관리하여 커널 모드 진입 비용을 제거합니다. 특히 코루틴은 스케줄러에 의한 강제 전환이 아닌, 코드 내에서 명시적으로 양보(yield)하여 전환하는 비선점형(Non-preemptive) 협력적 멀티태스킹 방식을 사용하여 오버헤드가 극도로 낮습니다.
8. 실제 OS의 스위칭 사례
- Linux: 리눅스는 프로세스와 스레드를 모두
task_struct라는 구조체로 관리합니다. schedule() 함수를 통해 다음 실행할 태스크를 결정하며, switch_to() 매크로를 통해 실제 레지스터 상태를 전환합니다.
- Windows: 윈도우는 스레드 기반 스케줄링을 수행합니다. 각 스레드는 KTHREAD 구조체를 가지며, 인터럽트 핸들러나 시스템 서비스 호출 시 디스패처가 개입하여 컨텍스트를 전환합니다.
# 컨텍스트 스위칭 (Context Switching)
## 1. 개요
**컨텍스트 스위칭(Context Switching)**이란 운영체제가 현재 실행 중인 프로세스나 스레드의 상태를 저장하고, 다음에 실행할 프로세스나 스레드의 상태를 복원하여 CPU의 제어권을 전환하는 과정을 말합니다. 이는 단일 CPU 환경에서도 여러 프로그램이 동시에 실행되는 것처럼 보이게 하는 **멀티태스킹(Multitasking)**을 구현하는 핵심 메커니즘입니다.
## 2. 동작 원리와 과정
CPU가 프로세스를 교체할 때, 이전에 수행하던 지점으로 다시 돌아와 작업을 계속하기 위해서는 현재까지의 진행 상태를 어딘가에 기록해두어야 합니다. 이때 사용되는 저장 공간이 **PCB(Process Control Block, 프로세스 제어 블록)**입니다.
### 2.1 PCB (Process Control Block)의 구성
PCB는 운영체제가 프로세스를 관리하기 위해 필요한 모든 정보를 담고 있는 데이터 구조체입니다. 주요 구성 항목은 다음과 같습니다.
* **PID (Process Identifier):** 프로세스를 고유하게 식별하는 번호
* **프로세스 상태 (Process State):** 생성, 준비, 실행, 대기, 종료 등의 현재 상태
* **프로그램 카운터 (Program Counter):** 다음에 실행할 명령어의 주소
* **CPU 레지스터 (CPU Registers):** 누산기, 인덱스 레지스터 등 CPU 내부의 현재 값
* **CPU 스케줄링 정보:** 우선순위, 스케줄링 큐 포인터 등
* **메모리 관리 정보:** 페이지 테이블, 세그먼트 테이블 등 메모리 할당 정보
* **입출력 상태 정보:** 할당된 I/O 장치, 열려 있는 파일 목록 등
### 2.2 스위칭 단계 비교
컨텍스트 스위칭은 크게 '현재 상태 저장'과 '새로운 상태 복원'의 두 단계로 나뉩니다.
| 단계 | 수행 작업 | 상세 내용 |
| :--- | :--- | :--- |
| **상태 저장 (Save)** | `Process A` $\rightarrow$ `PCB_A` | 현재 CPU 레지스터 값, 프로그램 카운터 등을 `PCB_A`에 기록 |
| **상태 복원 (Restore)** | `PCB_B` $\rightarrow$ `Process B` | `PCB_B`에 저장되어 있던 이전 상태 값을 CPU 레지스터로 로드 |
`[그림: 컨텍스트 스위칭 흐름도 - Process A의 상태가 PCB_A에 저장되고, PCB_B의 상태가 CPU로 복원되어 Process B가 실행되는 과정의 다이어그램]`
## 3. 스케줄러의 역할과 관계
컨텍스트 스위칭은 단독으로 일어나는 것이 아니라, 운영체제의 **스케줄러(Scheduler)**에 의해 결정됩니다.
* **스케줄러의 역할:** 준비 큐(Ready Queue)에 대기 중인 여러 프로세스 중 어떤 프로세스에 CPU를 할당할지 결정하는 알고리즘을 수행합니다.
* **상호작용 과정:**
1. 스케줄러가 CPU를 사용할 다음 프로세스를 선택합니다.
2. **디스패처(Dispatcher)**가 선택된 프로세스에 CPU 제어권을 넘기기 위해 실제 컨텍스트 스위칭을 수행합니다.
3. 이 과정에서 이전 프로세스의 컨텍스트는 저장되고, 선택된 프로세스의 컨텍스트가 복원됩니다.
## 4. 컨텍스트 스위칭의 발생 조건
멀티프로그래밍 환경에서 다음과 같은 상황이 발생할 때 컨텍스트 스위칭이 트리거됩니다.
1. **인터럽트(Interrupt) 발생:** 하드웨어 장치(키보드, 마우스, 디스크 등)가 CPU에 신호를 보내 즉각적인 처리가 필요할 때 발생합니다.
2. **시스템 콜(System Call) 호출:** 프로세스가 I/O 작업(파일 읽기/쓰기 등)을 요청하여 CPU를 사용할 수 없는 '대기(Waiting)' 상태로 전환될 때 발생합니다.
3. **타임 슬라이스(Time Slice) 만료:** 시분할 시스템(Time-sharing system)에서 각 프로세스에 할당된 최대 CPU 사용 시간(Quantum)이 종료되어 강제로 CPU를 반납해야 할 때 발생합니다.
## 5. 오버헤드와 성능 영향
컨텍스트 스위칭은 논리적으로는 필수적이지만, 물리적으로는 아무런 유용한 작업을 수행하지 않는 **오버헤드(Overhead)** 시간을 발생시킵니다.
* **CPU 시간 낭비:** PCB 저장 및 복원 과정 자체에 CPU 사이클이 소모됩니다.
* **캐시 플러시(Cache Flush):** 프로세스가 바뀌면 기존 프로세스가 사용하던 L1, L2 캐시 메모리의 데이터가 무효화됩니다. 새로운 프로세스가 실행되면 다시 메모리에서 데이터를 읽어와 캐시를 채워야 하므로, 스위칭 직후에는 메모리 접근 속도가 일시적으로 저하되는 **캐시 미스(Cache Miss)** 현상이 빈번하게 발생합니다.
## 6. 프로세스 vs 스레드 컨텍스트 스위칭
프로세스 간 스위칭보다 스레드 간 스위칭이 훨씬 효율적입니다. 이는 메모리 공유 구조의 차이 때문입니다.
### 6.1 차이점 분석
* **프로세스 스위칭:** 서로 독립된 메모리 공간(Code, Data, Heap, Stack)을 가지므로, 가상 메모리 주소 체계를 관리하는 페이지 테이블(Page Table)을 완전히 교체해야 하며 TLB(Translation Lookaside Buffer)를 비워야 합니다. 이때 프로세스의 상태는 **PCB(Process Control Block)**에 저장됩니다.
* **스레드 스위칭:** 동일한 프로세스 내의 스레드들은 스택(Stack) 영역을 제외한 메모리 공간을 공유합니다. 따라서 메모리 맵을 교체할 필요가 없으며, **TCB(Thread Control Block, 스레드 제어 블록)**에 저장된 레지스터와 스택 포인터만 변경하면 되므로 매우 빠릅니다.
* **TCB (Thread Control Block):** 운영체제가 각 스레드를 관리하기 위해 사용하는 데이터 구조체로, 스레드 ID, 스택 포인터, 프로그램 카운터, 레지스터 상태 등 스레드 고유의 실행 문맥을 저장합니다.
### 6.2 비교 요약표
| 구분 | 프로세스 컨텍스트 스위칭 | 스레드 컨텍스트 스위칭 |
| :--- | :--- | :--- |
| **전환 대상** | 서로 다른 프로세스 간 | 동일 프로세스 내 스레드 간 |
| **메모리 공유** | 공유하지 않음 (독립적) | 공유함 (Stack 제외) |
| **교체 항목** | PCB, 페이지 테이블, TLB 등 | TCB, 레지스터 |
| **오버헤드** | 매우 높음 (캐시 플러시, TLB 초기화 발생) | 상대적으로 낮음 (메모리 맵 유지) |
| **속도** | 느림 | 빠름 |
## 7. 최적화 방안
운영체제와 하드웨어 제조사는 컨텍스트 스위칭 비용을 줄이기 위해 다양한 기법을 도입하고 있습니다.
* **하드웨어적 지원:**
* **다중 레지스터 세트:** CPU 내부에 여러 세트의 레지스터를 두어, 포인터만 변경함으로써 즉시 컨텍스트를 전환하는 방식입니다.
* **ASID (Address Space Identifier):** TLB에 프로세스 식별자를 함께 저장하여, 스위칭 시 TLB 전체를 비우지 않고도 유효한 항목을 구분해 사용할 수 있게 합니다.
* **소프트웨어적 지원:**
* **효율적인 스케줄링 알고리즘:** 불필요한 스위칭 횟수를 줄이기 위해 적절한 타임 슬라이스 길이를 설정하거나, 우선순위 기반의 정교한 스케줄링을 적용합니다.
* **경량 프로세스(LWP) 및 코루틴(Coroutine):** 커널 수준이 아닌 사용자 수준에서 스위칭을 관리하여 커널 모드 진입 비용을 제거합니다. 특히 코루틴은 스케줄러에 의한 강제 전환이 아닌, 코드 내에서 명시적으로 양보(yield)하여 전환하는 **비선점형(Non-preemptive) 협력적 멀티태스킹** 방식을 사용하여 오버헤드가 극도로 낮습니다.
## 8. 실제 OS의 스위칭 사례
* **Linux:** 리눅스는 프로세스와 스레드를 모두 `task_struct`라는 구조체로 관리합니다. `schedule()` 함수를 통해 다음 실행할 태스크를 결정하며, `switch_to()` 매크로를 통해 실제 레지스터 상태를 전환합니다.
* **Windows:** 윈도우는 스레드 기반 스케줄링을 수행합니다. 각 스레드는 KTHREAD 구조체를 가지며, 인터럽트 핸들러나 시스템 서비스 호출 시 디스패처가 개입하여 컨텍스트를 전환합니다.