
ContextSwitch(문맥 교환)와 그와 관련된 개념을 학습한다.
ContextSwitch
1. ContextSwitch란 ?
CPU는 코어 1개당 하나의 스레드만 실행이 가능하다. 때문에 현재 실행 중인 프로세스,스레드를 멈추고 다른 프로세스, 스레드를 실행시켜야한다. 즉, CPU 코어에서 실행중이던 프로세스, 스레드가 다른 프로세스, 스레드로 교체되는 과정을 이야기한다. 매우 빠르게 진행되기 때문에 사용자 입장에선 동시에 여러 프로세스, 스레드가 실행되는 것처럼 보인다.
2. ContextSwitch가 필요한 이유
- 여러 스레드가 동시에 실행 중일 경우 하나의 스레드가 CPU를 독점하는 걸 막기 위해
- 브로킹 작업 발생
- 우선 순위가 높은 스레드의 등장
- OS 스케줄러가 차례가 끝났음을 판단
3. ContextSwitch 단계
- 인터럽트 또는 시스템 콜 방생: 타이머 인터럽트(시간 할당량 종료) or I/O 요청 발생
- 커널 모드 진입: CPU 제어권이 운영 체제로 넘어감
- 프로세스 A 상태 저장: 현재 CPU에 있는 레지스터 값, PC 등을 프로세스 A의 PCB(Process Control Block)에 저장
- 다음 프로세스 선택: 스케줄러가 다음에 실행할 프로세스 B를 결정
- 프로세스 B 상태 복원: 프로세스 B의 PCB에 저장되어 있던 정보를 CPU 레지스터로 불러옴
- 사용자 모드 복귀: 프로세스 B가 중단된 지점부터 다시 실행
이중 동작 모드 (Dual-mode operation)
1. 이중 동작 모드란 ?
CPU는 실행 중인 코드에 따라 권한을 분리하게 되고 이를 이중 동작 모드라고 부르며, 보통 CPU 내부의 Mode Bit (0 or 1)로 구분한다. 유저 모드와 커널 모드 구분이 없는 경우엔 메모리 침범, 자원 독점, 명력어의 등급제 같은 보안과 안정성 문제가 발생하게 된다.
- 메모리 침범
- 유저 모드에선 페이지 테이블(Page Table)이라는 허용된 구역에만 접근이 가능하다. 시스템 전체 접근을 위해선 커널 모드로 전환이 필요하다. 만약 유저 모드에서 유저가 해당 구역을 침범하려고 하면 CPU가 즉시 해당 프로그램을 Kill 시켜버린다.
ex) 악성 프로그램이 은행 앱이 사용 중인 메모리 영역에 접근이 가능하면 문제가 된다.
- 유저 모드에선 페이지 테이블(Page Table)이라는 허용된 구역에만 접근이 가능하다. 시스템 전체 접근을 위해선 커널 모드로 전환이 필요하다. 만약 유저 모드에서 유저가 해당 구역을 침범하려고 하면 CPU가 즉시 해당 프로그램을 Kill 시켜버린다.
- 자원 독점
- 하드웨어는 공유 자원이지만 프로그램은 이기적이기 때문에 자원을 나눠서 사용하려고 하지 않는다. 하드웨어가 일정 시간마다 CPU에게 제어권을 넘기라는 신호를 보내는데 이 신호는 무조건 커널 모드에서 실행된다.
- 명령어의 등급제
- CPU 명령어에는 시스템을 재부팅하거나 하드웨어 설정을 변경하는 명령어들이 있다. CPU가 가지는 강력한 명령어들은 특권 명령어라고 부르며, 이런 명령어는 오로지 커널 모드에서만 작동하게 된다. 만일 유저 보드에서 실행하려고 한다면 CPU가 실행을 거절하게 된다.
모드 전환
1. 유저 모드 (User Mode)
메모장, 브라우저, 게임 같은 일반 애플리케이션이 실행되는 모드이다. 시스템의 핵심 지원(하드웨어, 커널 영역 메모리 등)에 직접 접근할 수 없다. 만약 유저 모드인 프로그램이 잘못된 메모리 주소에 접근하거나 하드웨어를 직접 제어하려고 한다면 CPU가 강제로 중단시킨다. 유저 모드인 한 프로그램이 버그가 발생해도 운영 체제 전체에 영향을 주지 않도록 방어하는 역할을 한다.
2. 커널 모드 (Kernel Mode)
운영 체제의 핵심인 커널 코드가 실행되는 모드이다. CPU의 모든 명령어 실행이 가능하며, 메모리 전체와 하드웨어 장치에 직접 접근이 가능하다. 프로세스 관리, 메모리 할당, 입출력 처리 등 시스템의 모든 생사여탈권을 가지고 있다. 커널 모드의 코드가 잘못 실행되면 시스템 전체가 중단될 수도 있다.
3. 모드 전환 (Mode Switch) vs 컨텍스트 스위칭 (Context Switch)
- 모드 전환 이란?
- 실행 주체는 그대로이지만 시스템 콜이 발생해, 권한만 유저 -> 커널로 변경
- 컨텍스트 스위칭이란 ?
- 실행 중인 프로세스 자체가 A -> B로 변경
시스템 콜과 인터럽트는 둘 다 모드 전환이 발생하지만 다른 개념이기 때문에 헷갈라지 않게 주의가 필요하다 !
| 구분 | 시스템 콜 | 하드웨어 인터럽트 |
| 발생 원인 | 프로세스가 의도적으로 호출 | 외부 장치가 비정기적으로 발생 |
| 모드 전환 | 무조건 발생 (유저 -> 커널) | 무조건 발생 (유저 -> 커널) |
| 컨텍스트 스위칭 | 상황에 따라 다름 (필요시에만) | 타이머 인터럽트 경우일 경우 거의 발생 (스케줄러가 실행 가능 프로세스가 있다고 판단 경우에만) |
| 동기 / 비동기 | 동기 | 비동기 |
3. 유저가 파일을 저장 할때 내부 동작
ex) 파일을 저장하는 상황 (모드 전환만 발생)
- 저장 액션 발생(유저 모드): 유저 모드는 하드웨어에 직접 접근 불가능
- 시스템 콜 호출(유저 모드가 커널 모드에 요청할때 호출 됨) -> 파을 저장 요청
- OS가 권한 확인(커널 모드): 사용자 권한, 파일명, 디스크 용량 등을 확인
- 대행: 검사를 통과하면 OS가 커널 모드의 권한으로 디스크 컨트롤러에 명령을 내려 저장
인터럽트
1. 인터럽트란 ?
인터럽트는 실행 중인 흐름을 방해하고 중단 시킨다는 뜻으로 CPU가 유저 모드에서 애플리케이션이 실행 중일때 중요한 다른 일이 생기면 이를 즉각 처리하기 위해 커널 모드로 전환하는 방식을 의미한다.
2. 하드웨어 인터럽트 (외부 인터럽트)
- 타이머 인터럽트 (Timer Interrupt)
- 하나의 프로그램이 CPU 독점하는 것을 막기 위해 하드웨어는 Timer Interrupt를 사용하게 된다. 정해진 시간(OS별로 다름)이 지나면 사용자 프로그램에서 운영체제로 CPU 제어권이 넘어가도록 하는데 이때 발생하는게 Interrupt이다. 이때 유저모드 -> 커널 모드 전환이 일어나도 CPU 제어권은 OS로 넘어가게 된다.
- 타이머 인터럽트가 없다면 CPU 독점을 막을 방법이 없다.
- I/O 인터럽트
- 입출력 장치에서 일어나는 인터럽트이다. 사용자가 키보드나 마우스를 사용할 경우, 디스크 컨트룰러가 알릴 때, 네트워크 관련에서 발생한다.
3. 소프트웨어 인터럽트 (내부 인터럽트)
- Exception
- 프로그램이 실행 중 예외 상황이 발생하면 CPU가 더 이상 진행하지 못하게 예외를 발생시킨다.
- 프로그램이 자신의 메모리 영역 외에 권한 없는 작업을 시도하려고 할때 발생시킨다.
- 시스템 콜 (System Call)
- 유저 모드에서 프로그램이 의도적으로 커널 모드로 전환을 하기 위해 발생시키는 인터럽트이다.
IDT (Interrupt Descriptor Table)와 PCB (Process Control Block)
1. IDT (Interrupt Descriptor Table) 이란?
인터럽트가 발생했을 때 어디로 가야하는지 알려주는 역할이다. 코어당 1개의 IDT를 가지고 있어서 과거엔 싱글 코어로 이루어져 있기 때문에 IDT가 한개였지만 최근엔 멀티 코어로 이루어져 있어 코어의 개수만큼 IDT를 가지고 있다.
IDT는 어떤 일이 발생했을때 사건별 대응 메뉴얼인 시스템 전체가 공유하는 하나의 통일된 규칙이다. 때문에 n개가 있어도 다 같은 내용을 가지고 있다.
2. PCB (Process Control Block)
CPU 코어는 한 번에 하나의 일만 처리할 수 있기 때문에 빠른 속도로 빠르게 프로세스를 교체하면서 일을 수행한다. 이때 나중에 다시 작업을 이어갈 상태를 어딘가에 저장하게 되는데 이 저장 공간을 PCB라고 부른다. 프로세스마다 하나씩 가지고 있는 저장 공간이다. 아래와 같은 정보들을 저장한다.
- Process State: 실행, 준비, 대기 등 현재 상태
- Program Counter (PC): 다음에 실행할 명령어의 주소
- Registers: CPU 레지스터에 담긴 중간 계산 값들
- Memory Management 정보: 페이지 테이블, 세그먼트 테이블 등
3. IDT vs PCB
| 구분 | IDT | PCB |
| 개수 | 코어당 1개 (전역) | 프로세스당 1개 (개별) |
| 목적 | 사건별 처리 코드 주소 안내 | 프로세스 상태 저장 및 복구 |
| 비유 | 문제 발생시 대응 메뉴얼 | 개별 기록부 |
| 시점 | 인터럽트가 발생한 순간 참조 | 컨텍스트 스위칭이 일어날 때 참조 |
4. 인터럽트 발생시 커널 스택이란 ?
인터럽트가 발생하게 되면 바로 PCB에 저장 되는 것이 아닌 커널 스택이라는 저장소를 거치게 된다.
- 하드웨어가 커널 스택에 자동 저장
인터럽트가 발생한 순간, CPU 하드웨어는 현재 실행 중인 프로세스 최소한의 정보들을 해당 프로세스의 커널 스택에 자동으로 push한다. - ISR (인터럽트 서비스 루틴)이 추가 저장
IDT를 타고 넘어온 커널 코드(IRS)가 실행 된다. - 컨텍스트 스위칭 결정 시 PCB로 복사
만약 타이머 인터럽트였고, 다른 프로세스로 변경해야 된다는게 결정 된다면 커널 스택에 있던 값들을 PCB에 복사 후 커널 스택 보인터를 저장하고 다음 프로세스를 호출한다.
스택과 PCB가 분리되어 있는 이유는 효율성과 중첩 때문이다. PCB는 프로세스마다 개별이기 때문에 여러 인터럽트가 발생하게 된다면 스택으로 쌓기 어렵다는 문제가 있다. 이런 문제를 해결하기 위해 커널 스택으로 분리를 하여 인터럽트가 중첩 되어도 스택을 차례대로 해결할 수 있다.
컨텍스트 스위칭은 레지스터를 스택에 넣고 다시 PCB로 옮기는 복잡한 과정이 반복되기 때문에 자주 발생하게 된다면 비용이 커지게 된다.