저번 포스트에서 한번 살펴봤지만 다시 보자면,
멀티프로세스 환경에서 CPU가 어떤 하나의 프로세스를 실행하고 있는 상태에서 인터럽트 요청에 의해 다음 우선 순위의 프로세스가 실행되어야 할 때 기존의 프로세스의 상태 또는 레지스터 값(Context)을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값(Context)를 교체하는 작업을 Context Switch(Context Switching)라고 한다.
쉽게 생각해서 CPU에서 실행중인 프로세스 혹은 스레드를 다른 프로세스 혹은 스레드로 교체하는 일련의 과정을 말한다.
Switch는 아주 쉽게 이해된다. 그러나 여기서 말하는 Context는 무엇을 의미할까?
Context란 CPU가 해당 프로세스를 실행하기 위한 해당 프로세스의 정보들을 의미한다.
가령 프로세스의 번호라던지, 프로세스의 코드가 어디까지 실행됐다던지 하는 정보들말이다.
이러한 Context는 프로세스의 PCB(Process Control Block)에 저장된다.
그래서 Context Switching때 PCB의 정보를 읽어(적재) CPU가 전에 프로스세가 일을 하던 것에 이어서 수행이 가능한 것이다.
PCB는 프로세스에 대한 모든 정보가 모여있는 곳으로, Task Control Block(TCB) 이라고도 한다.
PCB안에는 프로세스의 상태, 프로세스 번호(PID), 해당 프로세스의 program counter(pc), register값, MMU정보, CPU점유 시간 등이 포함되어 있다.
PCB는 운영체제 내부의 프로세스를 관리하는 코드 부분에 저장되어 있다.
CPU는 한 프로세스가 종료될 때까지 수행하는 것이 아니라 여러 프로세스를 중간 중간에 바꿔가면서 수행한다.
그러므로 CPU는 수행중인 프로세스를 나갈 때, 이 프로세스의 정보를 어딘가에 저장하고 있어야 다음에 이 프로세스를 수행할 때 이전에 수행한 그 다음부터 이어서 작업할 수 있다.
이러한 정보를 저장하는 곳이 PCB이다.
그렇다면 왜 Context Switching이 필요한 것일까?
만약 컴퓨터가 매번 하나의 프로세스만 처리할 수 있다면, 해당 프로세스가 끝날때까지 다음 프로세스는 기다릴 수 밖에 없다.
하지만 사람들은 당연하게도 많은 프로세스들이 동시에 실행되길 바랬고,
어떻게 보면 굉장히 비효율적인 방법을 떠올렸다고 볼 수 있다.
그것은 굉장히 빠른 속도로 프로세스를 번갈아 가면서 cpu에서 실행시키는 것이다.
내가 굉장히 좋아하는 유튜버 쉬운코드님이 그리신 그림을 봐보자.
각각 P1, P2는 서로 다른 프로세스를 의미한다. 블록 하나는 cpu에서 실행되는 프로세스의 단위를 뜻하는 데, 이를 cpu 타임슬라이스라고 한다.
각각의 타임슬라이스는 거의 밀리세컨드 단위인데, 위 그림의 P1, P2 블락 사이사이마다 Context Switching이 일어나는 것이다.
CPU는 항상
이렇게 작업하고 있는 것이다. 그것도 쉴새 없이 말이다.
인간이 느낄 수 없을 정도로 빠르게 번갈아가며 작업을 하니 우리는 동시에 프로세스가 돌아간다고 느끼게 되는 것이다. 이를 멀티태스킹이라고 하며, 멀티태스킹의 목적은 프로세스의 응답 시간을 최소화하는 데 있다.
이렇기 때문에 내가 어떻게 보면 굉장히 비효율적인 방법이라고 한 것이다.
CPU에서 실행중이던 프로세스의 정보를 PCB에 저장 -> 다음 실행할 프로세스의 PCB에 있는 정보 로드 -> 실행
을 밀리세컨드 단위로 반복하고 있는 것이기 때문이다.
RAM에 적재된 프로세스는 한 개가 아니기 때문에 프로세스가 CPU의 서비스를 받으려면 순서를 기다려야 한다.
이 순서는 몇 가지 Queue에 의해 관리가 되며 스케쥴링을 위한 Queue는 크게 세 종류가 있다.
Job Queue
프로세스가 시스템에 들어오면 job queue에 놓인다.
RAM은 용량이 적기 때문에 원하는 프로그램을 모두 RAM으로 옮길 수 없고, 따라서 RAM으로 올라올 프로그램을 정하는 queue가 job queue이다.
하드 디스크에 있는 프로그램이 실행되기 위해 메인 메모리의 할당 순서를 기다리는 queue.
Ready Queue
CPU 점유 순서를 기다리는 queue
Device Queue
I/O를 하기 위한 여러 장치가 있는데, 각 장치를 기다리는 Queue가 각각 존재한다.
위와 같이 여러 큐가 존재하는데, 각 큐 내부에 저장된 실제 데이터는 각 프로세스의 PCB가 저장되어 있다.
그리고 이러한 순서를 기다리는 공간이 있다면 이 순서를 정해주는 알고리즘이 있어야 한다.
이러한 알고리즘을 스케줄링(Scheduling)이라 한다.
Job Queue - Job Scheduler(Long-term scheduler)
Ready Queue - CPU Scheduler(Short-term scheduler)
Device Queue - Device Scheduler
Job queue의 순서를 정해주는 job scheduler를 long-term scheduler라고도 하는데, 이는 이 스케줄링이 발생하는 시간이 비교적 오래걸리기 때문이다.(대략 초~분) 반면에 ready queue의 스케줄러를 short-term scheduler라고도 하는데, 이는 스케줄링이 발생하는 시간이 매우 짧기 때문이다. CPU scheduling은 말 그대로 프로세스가 CPU를 점유하는 순서를 정해주는데 이는 매우 빠른 시간안에 이루어져야한다. 현대 컴퓨터가 여러 프로그램을 동시에 사용하는 것과 같은 효과를 주는 이유가 이 스케줄링 속도가 매우 빠르게 이루어지기 때문이다.
CPU를 사용하려고 하는 프로세스들 사이의 우선순위를 관리하는 작업 - 자원을 어떤 프로세스에 얼마나 할당하는지 정책을 만드는 것
프로세스들에게 자원을 최대한 공평하게 배분하며 처리율과 CPU 이용률을 증가시키고, 오버헤드, 응답시간(Response time / Turnaround time), 대기시간을 최소화하기 위한 기법
선점형 스케줄링(Preemptive Scheduling) 과 비선점형 스케줄링(Non-preemptive / Cooperative Scheduling) 이 있음
메모리에 여러 개의 프로세스를 올려놓고(다중 프로그래밍), CPU의 가동시간을 적절히 나누어(시분할) 각각의 프로세스에게 분배하여 실행
실행 상태에 있던 프로세스가 I/O 요청 등에 의해 Block 상태가 되는 경우
실행 상태에 있던 프로세스가 타이머 인터럽트 발생에 의해 준비 상태로 되는 경우
I/O 요청으로 Block 상태에 있던 프로세스의 I/O 작업이 완료되어 인터럽트가 발생하고, 그 결과 이 프로세스의 상태가 준비 상태로 바뀌는 경우
CPU에서 실행 상태에 있는 프로세스가 종료되는 경우
하나의 프로세스가 CPU를 차지하고 있을 때, 우선순위가 높은 다른 프로세스가 현재 프로세스를 중단시키고 CPU를 점유하는 스케줄링 방식
한 프로세스가 CPU를 할당받으면 작업 종료 후 CPU 반환 시까지 다른 프로세스는 PCU 점유가 불가능한 스케줄링 방식
스케줄링 알고리즘에 대해서는 다음번에 알아보도록 하자.
종합적으로 느낀 점이라고 하면
이렇게 고생하는 CPU가 굉장히 인상깊었다.
원래 알고있었지만 더 와닿아서 고맙기도하고 미안하기도 한 복합적인 감정이 든다.