개요
프로세스들이 실행되기 위해서는 CPU가 필요하다.
따라서 운영체제는 프로세스들에게 어떻게 CPU자원을 분배할 것인지 정해야한다.
이를 CPU 스케줄링 (CPU scheduling)이라고 한다.
프로세스마다 먼저 처리해야하는 이른바 우선순위가 높은 프로세스가 있다.
이 중에는 대표적으로 입출력 작업이 많은 프로그램이 될 수 있다. 프로세스는 입출력 작업 도중에는 대기 상태에 접어들기 때문에 그만큼 CPU 작업이 많은 프로그램에 CPU자원을 집중적으로 할당할 수 있기 때문이다.
프로세스는 모두 입출력 장치와 CPU 둘 다 필요로 하며 실행된다. 이때 입출력 작업이 많은 프로세스를 입출력 집중 프로세스(I/O bound process)라고 하고, 반대로 CPU 작업이 많은 프로세스를 CPU 집중 프로세스(CPU bound process)라고 한다.
위와 같이 CPU 집중 프로세스와 입출력 집중 프로세스가 동일한 빈도로 CPU를 사용하는 것은 비효율적이다. 입출력 작업을 완료하기 전까지는 입출력 집중 프로그램은 어차피 대기 상태일테니 말이다.
이렇게 여러 경우에 따라 운영체제는 프로세스마다 프로세스의 PCB에 우선순위(priority)를 부여한다.
그리고 당연히, 우선순위가 더 높은 프로세스는 자주 실행된다.
우선순위가 높은 순서대로 처리하기 위해 운영체제가 모든 프로세스의 PCB를 찾아보는 것은 매우 비효율적이다.
그래서 운영체제는 스케줄링 큐(scheduling queue)로 프로세스들을 관리한다.
스케줄링 큐는 메모리에 적재해야하는 프로세스들을 큐에 삽입한다. 이때, 큐에는 종류가 있는데 대표적으로 준비 큐와 대기 큐가 있다.
준비 큐(ready queue)는 CPU를 이용하고 싶은 프로세스들이 삽입되고 대기 큐(waiting queue)(waiting queue)는 입출력장치를 이용하기 위해 대기 상태에 들어간 프로세스가 삽입되는 큐를 의미한다.
큐는 기본적으로 선입선출(FIFO) 자료구조를 뜻하지만, 스케줄링 큐는 꼭 그렇지는 않다.
프로세스들이 삽입된 큐에서 먼저 처리할 프로세스를 꺼낼 때, 빨리 삽입된 프로세스를 먼저 처리하는 것이 아닌 우선순위가 더 높은 프로세스를 처리하게된다.
입출력 장치를 사용하기 위해 대기상태에 접어든 프로세스도 마찬가지이다. 이때, 똑같은 입출력 장치를 사용하려는 프로세스들이 있기마련인데, 이 프로세스들은 입출력 장치 종류에 따른 큐에 삽입되게 된다.
예를 들어 프로세스가 하드 디스크를 원한다면 하드 디스크 대기 큐에서, 프린터를 원한다면 프린터 대기 큐에서 작업이 완료되기를 기다린다.
그리고 입출력이 완료되어 완료 인터럽트가 발생하게 되면 운영체제는 대기 큐에서 작업이 완료된 PCB를 찾는다. 그 후 PCB의 상태를 '준비'로 변경하고 대기 큐에서 제거, 준비 큐로 이동시킨다.
선점형 스케줄링(preemptive scheduling)은 하나의 프로세스가 자원을 독점할 수 없는 스케줄링 방식이다.
대부분의 운영체제에서는 선점형 스케줄링 방식을 사용하고 있는데, 예시로 운영체제가 프로세스마다 자원 사용 시간을 분배하고 프로세스가 분배받은 시간을 전부 소모하면 타이머 인터럽트가 발생하여 차례가 끝나는 것을 선점형 스케줄링의 방식으로 볼 수 있다.
반대로 비선점형 스케줄링(non-preemptive scheduling)은 하나의 프로세스가 자원을 독점할 수 있는 방식이다.
이 방식은 현재 자원을 사용 중인 프로세스가 있을 때, 이 프로세스가 종료되거나 대기 상태에 접어들기 전까지 다른 프로세스가 자원을 사용할 수 없는 스케줄링 방식을 의미한다.
둘 다 장단점이 있는데, 먼저 선점형 스케줄링은 고루 자원을 분배할 수 있지만, 문맥 교환 과정에서 오버헤드가 발생 할 수 있다는 단점이 있다.
비선점형 스케줄링은 오버헤드가 덜 발생하지만, 당장 자원을 사용해야하는 프로세스가 발생할 때, 이미 자원을 사용 중인 프로세스가 있다면 급한 상황에서도 해결하지 못하는 상황이 발생할 수 있다는 단점이 있다.