Computer가 매번 하나의 Task만 처리할 수 있다면 ?
- 해당 Task가 끝날때까지 다음 Task는 기다릴 수 밖에 없습니다.
- 또한 반응 속도가 매우 느리고 사용하기 불편합니다.
그렇다면 다양한 사람들이 동시에 사용하는 것처럼 하기 위해선 ?
- Computer multitasking을 통해 빠른 반응속도로 응답할 수 있습니다.
- 빠른 속도로 Task를 바꿔 가며 실행하기 때문에 사람의 눈으론 실시간처럼 보이게 되는 장점이 있습니다.
- CPU가 Task를 바꿔 가며 실행하기 위해 Context Switching이 필요하게 되었습니다.
PCB (Process Controll Block)
프로그램 실행 -> 프로세스 생성 -> 프로세스 주소 공간에(코드, 데이터, 스택) 생성 -> 이 프로세스의 메타데이터들이 PCB에 저장
프로세스 제어 블록 (Process Control Block, PCB)
- 특정 프로세스에 대한 중요 정보를 저장하고 있는 커널 내의 자료 구조.
- OS는 프로세스를 관리하기 위해 프로세스의 생성과 동시에 고유한 PCB를 생성한다.
- 프로세스는 CPU를 할당받아 작업을 처리하다가 프로세스 전환이 발생하면 진행하던 작업을 저장하고 CPU를 반환해야 한다. 이때 작업의 진행 상황을 모두 PCB에 저장한다. 그리고 다시 CPU를 할당받게 되면 PCB에 저장되었던 내용을 불러와 종료되었던 시점부터 다시 작업을 수행한다.
PCB(Process Control Block) 상세구조
- PID 프로세스 식별자: 프로세스 식별 번호
- 프로세스 상태, new, running, waiting, terminated ...
- 프로그램 카운터(Program Counter, PC): 프로세스가 다음에 실행할 명령어의 주솟값
- CPU Registers: accumulator, index register, stack pointers, general purpose registers
- CPU 스케쥴링 정보: 프로세스 우선순위, 스케쥴 큐에 대한 포인터 등
- 메모리 관리 정보: 페이지 테이블 or 세그먼트 테이블과 같은 정보 포함
- 입출력 상태 정보: 프로세스에 할당된 입출력 장치들과 열린 파일 목록
PCB가 필요한 이유 ?
- CPU에서는 프로세스의 상태에 따라 교체 작업이 이루어집니다. (인터럽트가 발생해서 할당받은 프로세스가 Block 상태가 되고 다른 프로세스를 running으로 바꿀 때)
이때, 앞으로 다시 수행할 Block 상태의 프로세스의 상태값을 PCB에 저장해두는 것입니다.
PCB 관리방식
Linked List 방식으로 관리 됩니다.
PCB List Head에 PCB들이 생성될 때마다 붙게 됩니다. 주솟값으로 연결이 이루어져 있는 연결 리스트 형태로, 삽입 삭제가 용이합니다.
즉, 프로세스가 생셩되면 해당 PCB가 생성되고 프로세스 완료 시 제거가 됩니다.
이렇게 수행 중인 프로세스를 변경할 때, CPU의 레지스터 정보가 변경되는 것을 Context Switching이라고 합니다.
Context Switching이란 ?
- CPU는 한번에 하나의 프로세스만 처리할 수 있다.
- 여러 프로세스를 처리해야 하는 상황에서 현재 진행중인 Task(프로세스, 스레드)의 상태를 PCB에 저장하고 다음에 진행할 Task의 상태값을 읽어 적용하는 과정이다.
- 다른 프로세스에게 CPU를 할당해 작업을 수행하는 과정이다.
콘텍스트 스위칭에서 콘텍스트가 무엇일까 ?
콘텍스트(Context)
- OS에서의 콘텍스트란 CPU가 해당 프로세스를 실행하기 위한 프로세스의 정보를 말하는 것이다.
그러면 어떤 정보 덕분에 스위칭이 가능한 것일까?
여러 정보가 있겠지만 핵심은 프로그램 카운터(Program counter, PC)와 스택 포인트(Stack Pointer, SP)이다.
프로그램 카운터(Program counter, PC)
- 마이크로프로세서 내부에 있는 레지스터 중의 하나로서, 다음에 실행될 명령어의 주소를 가지고 있어 실행할 기계어 코드의 위치를 지정한다. 간단히 코드 한줄한줄을 가리키는 주소 레지스터라고 생각하면 된다.
마이크로프로세서: CPU안에 기계어를 상대적으로 쉽게 추가할 수 있도록 이용하는 방식인 '마이크로코드'를 사용한다는 동작 방식 자체에 초점을 맞춘 용어이므로 CPU랑 동일하게 생각하면 된다.
스택 포인터(Stack Pointer, SP)
- CPU안에서 스택에 데이터가 채워진 마지막 위치를 가리키는 레지스터다. 스택 특성상 스택 포인터가 가리키는 곳까지가 데이터가 채워져 있는 영역이고 그 이후부터 스택의 끝까지는 데이터가 없는 영역인 것이다. 즉, 스택에 새로운 데이터가 추가되거나 제거되면 스택 포인터의 값이 증가하거나 감소한다.
이렇게 기계어 코드 위치 정보와 스택의 데이터 위치 정보 덕분에 콘텍스트 스위칭이 일어나더라도 프로세스 간, 스레드 간 전환이 가능한 것이다.
그렇다면 콘텍스트 스위칭은 언제 발생할까 ?
인터럽트(Interrupt)
- CPU가 프로그램을 실행하고 있을 때 실행 중인 프로그램 밖에서 예외 상황이 발생하여 처리가 필요한 경우 CPU에게 알려 작동이 중단되지 않고 예외 상황을 처리할 수 있도록 하는 기능을 말한다.
콘텍스트 스위칭은 아래와 같은 인터럽트 요청이 와야 발생한다.
1. 입/출력을 요청할 때
2. CPU 사용시간이 만료되었을 때
3. 자식 프로세스를 만들 때
4. 인터럽트 처리를 기다릴 때
Context Switching 과정
- Task의 대부분 정보는 Register에 저장되고 PCB로 관리된다.
- 현재 실행하고 있는 Task의 PCB 정보를 저장한다.
- 다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행할 수 있다.
P1, P2라는 2개의 프로세스가 있고 CPU에 올라갔다 내려갔다 하는 과정을 보여준다.
- Process P1을 실행하다가 PCB1에 상태를 저장한다.
- 저장되어 있는 PCB2를 재로드해서 실행시킨다.
- 다시 PCB2 상태를 저장한다.
- PCB1을 재로드하여 실행시킨다.
많은 비용이 소모되는 Context Switching
- Cache 초기화
- 메모리 매핑 초기화
- 커널은 항상 실행되어야 한다.
프로세스가 스레드보다 더 많은 비용이 든다.
✅ 스레드는 Stack 영역을 제외한 모든 메모리를 공유하기에 Context Switching 발생 시에 Stack 영역만을 변경하면 된다.
✅ 프로세스는 공유하는 메모리가 없기에 캐시 메모리 초기화 등의 무거운 작업을 해야한다