본문 바로가기

[운영체제] 04-2 프로세스 스케줄링 Process Scheduling

출처 서울대학교 홍성수 교수님, [K-MOOC] 운영체제의 기초, 4주차 Processes and Threads

 

Process Scheduling이란?

프로그램이 수행을 하려면 먼저 컴퓨터 시스템에 있는 많은 자원들을 부여받아야 된다. 대표적인 것이 메모리 자원, CPU 자원, I/O 디바이스 자원뿐만 아니라 커널이 관리하는 자료 구조(페이지 테이블 등) 이런 것들을 할당받아야 한다. 프로세스가 특정 시점에 할당받은 자원을 process state라고 하면, 이의 집합을 context라고 한다. context를 갖는 프로세스는 라이프 사이클 동안에 state transition한다. process scheduling이란 프로세스의 state를 전환하는 것이다.

 

process scheduling와 synchronization은 process management에서 가장 중요한 부분이다.

OS에서 process scheduling이란 여러 프로세스들이 CPU를 공유하는 환경에서 다음에 돌아야 될 프로세스를 선택하고 실행 중인 컨텍스트를 스위칭해주는 작업이다. 그런데 process scheduling을 할 때 다른 부작용을 초래하면 안 된다.

 

첫째, process scheduling은 공평해야 한다.

컴퓨터 시스템을 공유하는 많은 프로세스들이 어떤 적정한 progress를 만들 수 있을 정도의 CPU를 받게 되어야 한다. 각각의 프로세스가 실행될 기회를 가질 수 있도록 보장해주어야 한다.

 

둘째, protection이다.

여러 프로세스들이 CPU를 공유하게 되면 CPU 안에 있는 작은 리소스들, register들도 공유하게 된다. 한 프로세스의 수행이 먼저 수행하던 프로세스에서 레지스터들을 다 망쳐버린다면 그러면 올바른 수행 결과가 안 나오게 되니 주의해야 한다.

 

스케줄링 메커니즘과 스케줄링 정책

스케줄링을 하기 위해 필요한 메커니즘은 공유하지만 목적에 따라서 어떤 스케줄링을 할 것인가는 교체할 수 있어야 한다. 이런 의미에서 OS의 프로세스 스케줄러는 아래와 같이 두 개의 layer로 구성이 되어 있다고 할 수 있다. 

 

아래 layer는 scheduling policy들이 공유하는 메커니즘이다. 우리는 이것을 dispatcher 메커니즘이라고 말한다.

그 위 레이어에는 여러 개의 scheduling policy들이 있다. 필요에 따라서 어느 하나의 정책을 호출해서 사용할 수 있다.

 

Dispatcher

Dispatcher는 운영체제의 가장 안 속 깊은 곳에 있는 일종의 무한루프라고 생각하면 된다.

  1. Dispatcher는 본인이 과거에 선택한 프로세스를 한동안 수행을 시킨다.
  2. 그러다가 rescheduling을 해야 될 필요가 발생을 하게 되면 현재 수행 중인 프로세스의 수행을 중단시킨다.
  3. 그 프로세스의 context를 안전하게 대피시킨다.
  4. 새로 수행해야 될 next process를 선택하고 그 프로세스가 수행을 하기 위해서 필요한 저장된 context를 다시 로드해온다.
  5. 새 프로세스를 한동안 수행을 시킨다.

Dispatcher는 이런 것을 지속적으로 반복하는 무한루프를 돈다.

 

Dispatcher 메커니즘의 챌린지: 유저 코드를 수행시키다가 Dispatcher 코드를 실행하기

유저 코드를 수행시키다가 Dispatcher 코드를 수행시키는 일은 간단하지 않다.

유저 코드는 유저 모드에서, 커널 코드 dispatcher 코드는 커널 모드에서 수행된다. 즉, dispatcher 코드를 수행시키려면 모드 전환이 일어나야 한다. 모드 전환은 어떻게 일어나는가? 유저 모드에서 커널 모드로 모드 전환이 일어나려면 반드시 interrupt 메커니즘이 필요하다.

 

1. 하드웨어 인터럽트 - 선점 스케줄링

하드웨어 인터럽트는 비동기 인터럽트이다. 하드웨어 인터럽트 (예시: 타이머 인터럽트, 키보드 입력 인터럽트)는 지금 수행하고 있는 유저 코드와 무관하게 비동기적으로 발생한다. 하드웨어 인터럽트가 발생하면 선점 스케줄링이 시작된다. 커널 모드로 진입해서 Dispatcher가 수행된다.

 

2. 소프트웨어 인터럽트 - 비선점 스케줄링

소프트웨어 인터럽트는 동기적이다. 수행 중인 프로세스가 자발적으로 CPU를 양보하기 위해 Dispatcher를 호출한다. 이때는 커널 모드 진입을 위해 소프트웨어 인터럽트(예시: 시스템 콜, 에러 - divide by zero, 페이지 폴트)를 호출하고 이러한 형식의 스케줄링을 비선점 스케줄링이라고 한다.

 

시스템 콜

OS는 유저 프로세스들이 커널 서비스를 필요로 할 때 수행시켜줄 수 있는 커널 함수를 가지고 있다. 유저 프로세스들에게 커널 함수를 호출할 수 있는 API를 제공한다. 이를 시스템 콜 인터페이스라고 한다. 외관상 유저 프로세스가 함수 호출하는 것과 똑같다. 그렇지만 system call 호출의 경우 내부적으로 소프트웨어 인터럽트가 발생해서 모드 전환이 일어나고 시스템 콜 인터럽트 핸들링이 일어나서 시스템 콜 함수를 호출하고 다시 유저 모드로 돌아온다.

유저 프로세스에서 시스템 콜 함수를 호출해서 커널 함수가 수행 중일 때에도 ps 명령어로 확인해보면 유저 프로세스가 뜬다. 즉, 프로세스의 컨텍스트는 계속 동일하다. 유저 프로세스가 실행 중인 것이다. 다만 모드가 유저 모드가 아니고 커널 모드인 것이다.

 

커널에 대한 이해

커널은 OS의 핵심 부분을 말한다. 스케줄링, 동기화, I/O 서브시스템 부분 정도를 말한다.

커널은 active한 존재일까 passive한 존재일까?

 

유저 프로세스가 active하게 자원을 이용하면서 수행 결과를 만들어내듯이 커널도 그럴까? 커널은 프로세스가 아니라 프로그램이라고 보는 것이 더 타당하다. passive한 entity다. 커널은 커널 모드에서 수행할 수 있는 커널 함수와 interrupt service routine의 집합체, 즉 라이브러리이다. OS 내부에는 OS 대신 유저들에게 서비스들을 제공해주는 프로세스인 커널 데몬 프로세스가 있다. 이는 커널 모드에서 수행하는 프로세스이지만 운영체제의 일부는 아니다.

유저 프로세스가 커널 서비스가 필요하게 되면 커널 함수를 호출한다. 커널 함수를 수행하기 위해서는 커널 모드로의 전환이 필요하다. 이를 위해 유저 프로세스는 시스템 콜을 호출한다. 유저가 시스템 콜로 호출해도 인터럽트가 발생한다.

 

커널 스페이스 / 모드 Kernel Space / Mode

특권 명령을 수행시킬 수 있고, 메모리 접근에 대한 제약이 없는 상태이다.

 

유저 스페이스 / 모드 User Spce / Mode

특권 명령을 수행시킬 수 없는 제한적 모드이고, 메모리도 자신에게 할당된 공간만 사용할 수 있다.

 

CPU는 모드를 어떻게 관리할까? 모든 CPU에는 Processor Status Word (PSW)가 있다. 이러한 컨트롤 레지스터의 한 비트를 할애해서 모드 비트로 사용한다. 0이면 커널 모드, 1이면 유저 모드이다.