CS/Operating System

프로세스의 주소 공간, 프로세스 상태, 프로세스 스케줄링 큐

olsohee 2023. 12. 23. 18:51

프로세스의 주소 공간

프로그램이 실행되면 프로그램의 모든 코드와 데이터는 가상 메모리에 할당된다. 가상 메모리는 추상화된 메모리 공간으로, 각 프로세스마다 가상 메모리를 갖는다. 그러나 가상 메모리에 할당된 코드와 데이터는 물리적 메모리에 로드될 때까지 실제 메모리에 존재하지 않는다. 그리고 필요에 따라 물리적 메모리에 적재되거나 스왑 영역으로 스왑 아웃된다. 또한 가상 메모리 내의 논리적 주소를 물리적 메모리의 물리적 주소로 변환하는 과정이 필요한데, 이는 MMU(Memory Management Unit)라는 하드웨어 장치가 수행한다.

 

각각의 가상 메모리는 코드, 데이터, 스택으로 구성된다. 

  • 코드: 개발자가 정의한 프로그램 코드가 CPU가 수행할 수 있는 기계어로 변환되어 저장된다. 
  • 데이터: 전역 변수 등 프로그램이 사용하는 데이터가 저장된다.
  • 스택: 함수가 호출될 때 호출된 함수의 수행을 마치고 복귀할 주소 및 지역 변수와 같은 데이터가 임시로 저장된다. 

운영체제의 주소 공간

운영체제도 하나의 프로그램이므로 운영체제의 커널 역시 코드, 데이터, 스택 영역을 가진다. 

  • 코드
    • 자원 관리를 위한 코드
    • 시스템 콜, 인터럽트 처리 코드
    • 편리한 서비스를 제공하기 위한 코드
  • 데이터
    • 커널의 데이터 영역에는 각종 자원을 관리하기 위한 자료구조가 저장된다.
    • CPU나 메모리와 같은 하드웨어 자원을 관리하기 위한 자료구조 뿐만 아니라 현재 수행 중인 프로그램을 관리하기 위한 자료구조인 PCB를 각 프로세스마다 가진다. 
  • 스택
    • 함수 호출시 복귀할 주소, 즉 함수를 호출했던 코드의 메모리 주소가 저장된다.
    • 프로세스가 함수를 호출할 때 자기 주소 영역 내부의 함수를 호출하면, 복귀 주소가 자기 자신의 코드이기 때문에 자신의 스택에 복귀 주소를 저장한다. 그러나 프로세스가 시스템 콜이나 인터럽트 등 특권 명령을 수행하려 하고 이로 인해 커널의 코드가 실행되는 중에 함수 호출이 발생하면, 그 복귀 주소는 커널 내의 주소이기 때문에 사용자 프로그램의 스택이 아닌 커널 내의 스택, 그 중 해당 프로그램의 스택 영역에 저장된다.
    • 위와 같은 일은 각 프로세스에서 모두 일어날 수 있다. 따라서 복귀 주소를 저장하는 공간인 스택이 각 프로세스마다 존재한다. 
    • 한 가지 유의할 점은, 시스템 콜이나 인터럽트 발생으로 CPU의 수행 주체가 운영체제로 바뀔 때는 직전에 수행되던 프로그램의 복귀 정보가 스택이 아닌 PCB에 저장된다는 점이다. 그리고 커널 내에서 함수 호출이 일어나면 이때는 커널 내의 스택 중 해당 프로그램의 스택에 복귀 주소가 저장된다. 

사용자 모드와 커널 모드

사용자 프로그램이 사용하는 함수는 다음과 같다.

  • 사용자 정의 함수: 프로그래머 본인이 직접 작성한 함수
  • 라이브러리 함수: 프로그래머 본인이 직접 작성하지는 않았지만 이미 누군가 작성해놓은 함수를 호출만 하여 사용하는 경우
  • 커널 함수: 운영체제의 커널에 정의된 함수 (ex, 시스템 콜 함수, 인터럽트 처리 함수)

사용자 정의 함수와 라이브러리 함수는 해당 프로그램의 코드 영역에 존재한다. 반면 커널 함수는 사용자 프로그램의 주소 공간이 아닌, 운영체제 커널의 코드 영역에 존재한다.

 

호출 함수의 종류에 따라 프로세스의 실행 상태가 사용자 모드와 커널 모드로 구분된다. 

  • 사용자 모드: 사용자 프로그램이 자신의 주소 공간에 정의된 코드를 실행하는 것을 뜻한다. (모드 비트가 1인 상태)
  • 커널 모드: 시스템 콜 함수와 같이 커널에 정의된 코드를 실행하는 것을 뜻한다. (모드 비트가 0인 상태)

이때 주의할 점은, 비록 시스템 콜을 통해 사용자 프로그램의 코드가 아닌 운영체제 커널의 코드가 실행되지만, 그럼에도 시스템 콜이 수행되는 동안 커널이 실행 상태에 있다고 하지 않고 사용자 프로그램이 실행 상태에 있다고 말한다. 사용자 프로그램의 입장에서는 CPU를 운영체제 커널에게 빼앗겼지만, 커널의 코드가 실행되는 것이 사실상 사용자 프로그램이 해야 할 일을 대신 해주는 것이기 때문이다. 따라서 시스템 콜이 실행 중일 때도 여전히 사용자 프로그램은 실행 상태에 있다고 간주된다. 다만 사용자 프로그램이 자신의 코드를 실행하는 것과 구분하여, '프로세스가 커널모드에서 실행중'이라고 이야기 한다.

프로세스의 상태

  • 실행 상태: 프로세스가 CPU를 가진 채로 기계어 명령을 실행하고 있는 상태이다. 일반적으로 컴퓨터 시스템에서 CPU는 하나이므로 실행 상태에 있는 프로세스는 매 시점 하나뿐이다.
  • 준비 상태: CPU를 할당받지 못했지만 CPU만 보유하면 당장 명령을 수행할 수 있는 상태이다.
  • 봉쇄 상태: CPU를 할당받더라도 당장 명령을 실행할 수 없는 상태이다(ex, I/O 작업이 진행 중).

이 외에도 프로세스가 생성 중이거나 종료 중인 일시적인 상태를 각각 시작 상태, 완료 상태라고 부른다.

  • 시작 상태: 프로세스가 시작되어 그 프로세스를 위한 각종 자료구조는 생성되었지만 아직 메모리를 획득하지 못한 상태이다.
  • 완료 상태: 프로세스가 종료되었으나 운영체제가 그 프로세스와 관련된 자료구조를 완전히 정리하지 못한 상태이다.

프로세스 문맥, PCB(프로세스 제어 블록)

여러 프로세스가 함께 수행되는 시분할 시스템 환경에서는 타이머 인터럽트에 의해 짧은 시간 동안 CPU를 사용한 후 빼앗겼다가 다시 CPU를 획득하는 식으로 CPU 관리가 이뤄진다. 따라서 프로세스가 CPU를 다시 획득하면 이전에 어느 부분까지 명령을 수행했는지 직전 수행 시점의 상태를 재현해야 한다. 따라서 문맥 교환 과정에서 CPU가 다른 프로세스에게 넘어갈 때 운영체제는 기존 실행 중이던 프로세스의 문맥을 PCB에 저장해둔다.

 

프로세스 제어블록은 운영체제가 프로세스들을 관리하기 위한 자료구조로, 커널의 데이터 영역에 프로세스마다 PCB를 갖는다. PCB에는 다음과 같은 프로세스 문맥이 저장된다.

문맥 교환(Context Switch)

하나의 사용자 프로세스로부터 다른 사용자 프로세스로 CPU 제어권을 넘기는 과정을 문맥 교환이라고 한다. 이때 실행 중이던 프로세스의 문맥을 저장하고, 새롭게 실행될 프로세스의 문맥을 가져오는 등 PCB가 사용된다. 예를 들어 타이머 인터럽트가 발생했다고 가정하면, 원래 수행 중이던 프로세스는 프로세스 문맥을 자신의 PCB에 저장하고, 해당 프로세스를 준비 상태가 된다. 그리고 새롭게 CPU를 할당받은 프로세스는 실행 상태가 되고, 예전에 저장한 문맥을 PCB로부터 하드웨어로 복원시키는 과정을 거친다.

 

문맥 교환이 일어나는 경우는 다음과 같다. 

  • 사용자 프로세스가 CPU를 할당받고 실행되던 중에 타이머 인터럽트가 발생하는 경우
  • 실행 중이던 프로세스가 입출력 요청이나 다른 조건을 충족하지 못해 CPU를 회수당하고 봉쇄 상태가 되는 경우

그러나 다음의 경우는 문맥 교환이 아니다.

  • 시스템 콜이나 타이머 인터럽트 외의 인터럽트가 발생하는 경우: 이 경우에도 실행 위치 등 프로세스 문맥의 일부가 PCB에 저장되지만 이 과정은 사용자 프로세스 A에서 커널을 통해 사용자 프로세스 B로 넘어가는 것이 아니라, 사용자 프로세스 A에서 커널로 넘어가는 것이다. 즉, 하나의 프로세스의 실행 모드가 사용자 모드에서 커널 모드로 바뀌는 것일 뿐, CPU를 점유하는 프로세스가 다른 프로세스로 변경되는 것은 아니기 때문에 이는 문맥 교환이 아니다.

위와 같은 모드 변경에 비해 문맥 교환에는 훨씬 많은 오버헤드가 발생한다.  따라서 CPU 할당 시간을 너무 작게 세팅하여 타이머 인터럽트가 빈번하게 발생하여 문맥 교환이 빈번하게 발생하도록 하면 이에 드는 오버헤드가 상당히 커진다. 그러나 반대로, CPU 할당 시간을 너무 크게 설정하면 시분할 시스템의 의미가 퇴색되므로 적절하게 CPU 할당 시간을 정하는 것이 중요하다.

프로세스를 스케줄링하기 위한 큐

운영체제는 각 프로세스들을 큐에 넣어 관리한다. 큐의 종류는 다음과 같다. 

  • 작업 큐(job queue)
    • 시스템 내의 모든 프로세스들을 관리하기 위한 큐로, 프로세스의 상태와 무관하게 시스템 내에 있는 모든 프로세스가 작업 큐에 속한다. 따라서 작업 큐에 있다고 해서 반드시 메모리에 할당된 것은 아니다.
  • 준비 큐(ready queue)
    • CPU 사용을 위한 큐로,  준비 큐에 있는 프로세스들은 CPU만 할당받으면 당장 실행될 수 있는 준비 상태의 프로세스들이다.
    • 운영체제는 준비 큐의 제일 앞에 줄 서 있는 프로세스에게 제일 먼저 CPU를 할당한다. 이때 준비 큐에 프로세스들을 줄 세우는 방법은 CPU 스케줄링 방법에 따라 달라진다.
  • 장치 큐(device queue)
    • 장치 큐는 각 장치마다 존재한다.
    • 예를 들어 디스크에 입출력을 요청한 프로세스들은 디스크 입출력 큐에 줄을 서게 된다. 즉 장치 큐에 속한 프로세스의 상태는 봉쇄 상태이다.
    • 그러면 디스크 컨트롤러는 디스크 입출력 큐에 줄 서 있는 순서대로 프로세스들의 입출력 작업을 수행한다. 프로세스의 입출력 작업이 완료되면 디스크가 인터럽트를 발생시키고, 인터럽트 처리 루틴에 의해 입출력 작업이 완료된 해당 프로세스는 입출력 큐에서 빠져나와 CPU를 기다리는 준비 큐에 줄을 서게 된다.
  • 자원 큐
    • 장치 큐는 하드웨어 자원을 기다리는 프로세스들이 줄을 서는 공간이고, 자원 큐는 소프트웨어 자원을 기다리를 프로세스들이 줄을 서는 공간이다. (ex, 공유 데이터)
    • 데이터 일관성을 위해 공유 데이터는 매 시점 하나의 프로세스만 접근 가능하도록 해야 한다. 따라서 공유 데이터를 사용 중인 프로세스가 공유 데이터를 반납할 때까지 다른 프로세스가 CPU를 할당받았다 하더라도 공유 데이터에 접근하지 않고 기다려야 한다.
    • 따라서 여러 프로세스가 공유 데이터에 접근하려고 할 때, 공유 데이터를 기다리는 자원 큐에 줄을 서게 하여 순차적으로 공유 데이터에 접근하게 한다. 

이러한 큐들은 운영체제 커널의 데이터 영역에 보관된다. 즉 다음과 같이 커널의 데이터 영역에 다양한 큐를 두어 각 프로세스가 CPU를 기다리는지, 입출력을 기다리는지 등의 정보를 커널이 총체적으로 관리한다. 예를 들어 타이머 인터럽트가 발생하면 커널은 준비 큐를 참고하여 다음에 어느 프로세스에게 CPU를 할당할지 결정하고, 현재 실행 중인 프로세스는 준비 큐의 제일 뒤로 보낸다.

그리고 커널에서 관리되고 있는 큐들은 다음과 같이 포인터를 통해 각 프로세스의 PCB를 연결 리스트 형태로 관리한다.


Reference

  • 이화여자대학교출판문화원, 운영체제와 정보기술의 원리, 반효경

'CS > Operating System' 카테고리의 다른 글

CPU 스케줄링  (1) 2024.02.28
프로세스와 스레드  (0) 2023.12.27
보안 방법  (1) 2023.12.23
컴퓨터 시스템의 구조와 저장 장치  (1) 2023.12.23
운영체제란?  (1) 2023.12.20