스케쥴링 (Scheduling)은 여러 실행 흐름들에게
공정하고 합리적으로 CPU 자원을 배분하는 작업을 의미한다.

만약 컴퓨터가 하나의 실행 흐름만을 사용한다면,
스레드(Thread)도 스케줄링도 필요하지 않았을 것이다.

문제는 현대 시스템이 여러 프로세스를 동시에 실행하고,
각 프로세스가 다시 여러 스레드를 가지는 구조가 되었다는 점이다.

스케줄링 없이 이러한 실행 흐름들을 방치한다면,
CPU는 “누가 언제 실행될지”를 전혀 제어하지 못하게 된다.
그 결과, 운영체제는 다음과 같은 심각한 문제를 겪게 된다.

  1. 어떤 프로그램에서 while (1) { ... }과 같은 무한 루프를 사용한다면, CPU는 그냥 해당 프로그램의 실행 흐름에 갇혀 다른 프로세스나 스레드를 실행하지 못하게 되는 CPU 독점의 문제가 생길 것이다.

  2. 키보드 입력이나, 네트워크 패킷, GUI에서 일어나는 이벤트들이 CPU 자원을 받지 못하게 되어 키보드 입력이 늦어지거나, 네트워크 패킷이 드랍되거나, GUI 이벤트들이 늦게 나타나는 등의 문제가 생겨 컴퓨터와 사용자의 상호작용에 문제를 겪을 것이다.

  3. 커널은 인터럽트(Interrupt), 페이지 폴트(Page Fault), 시스템콜(System Call (syscall)) 등을 처리하고, 이러한 요청들은 요청이 들어온 즉시 수행하지 않으면 커널이 정상 동작할 수 없게 되어 커널 안정성이 붕괴될 것이다.

이러한 문제들을 발생하는 것을 막기 위해
운영체제는 CPU를 작은 시간 조각(time slice)으로 나누고,
해당 시간 조각을 단위로 이 시간에는 이 실행 흐름을 수행하도록,
저 시간에는 저 실행 흐름을 수행하도록 게획을 짠다.

이를 preemptive scheduling이라 하며,
현재 실행 중인 흐름에서 다른 실행 흐름으로 전환할 때 Context Switch가 발생하게 되었다.