본문 바로가기
대학교 공부/운영체제

운영체제 (3) - Process Description and Control

by 오답노트의 주인 2025. 6. 18.

2024년 1학기 운영체제 수업을 듣고 정리한 내용입니다. 수업 교재는 운영체제 - 내부구조 및 설계원리 8 판입니다.

Process

간단하게 말하면 실행중인 프로그램이다. 프로그램을 실행하기 위해서는 명령어와 데이터가 필요하다. 또한 시스템 자원과 연결된 정보들 그리고 실행중에 변경되는 프로그램의 상태를 나타내는 값 등이 프로세스에 포함된다.

프로세스의 구성요소

  • 명령어

  • 데이터 (전역 및 static 변수)

  • Stack (실행중에 저장될 임시 값들)

  • Process Control Block (PCB)

    프로세스가 생성되고 나서부터 종료될 때까지 필요한 정보들이다. 명령어와 데이터는 파일형태로 존재하지만 스택과 PCB는 OS가 프로세스를 생성할 때 동적으로 만들어진다.

Dispatcher

Multiprogramming 그리고 Time Sharing에서는 메모리에 올라와 있는 여러 프로세스중 하나를 선택하여 실행한다. 다른 프로세스를 선택하여 실행해야하는 때가 되면 어느 프로세스를 실행할 지 선택하여야 한다. 이 작업은 Dispatcher가 담당한다.

Dispatcher는 메모리에 올라온 프로세스들 중 실행 가능한 상태의 프로세스만 실행한다. 즉, 프로세스의 상태가 Ready여야만 실행한다. I/O 작업이나 기타 다른 이유로 Block된 프로세스라면 실행하지 않는다. 위 사진에서는 Process B가 실행 중에 Block 상태로 변하였기 때문에, A->B->C->A순으로 실행되다가 A->C로 실행 순서가 바뀐 모습이다.

프로세스들은 각 상태를 나타내는 큐에 진입한다. 프로세스의 상태가 Ready라면 Ready큐에 프로세스가 들어가 있고, Block된 상태라면 Block큐에 들어가 있을 것이다.

Process state

Five state

여기서 프로세스는 5가지의 상태를 갖는다.

상태 설명
New 프로세스가 생성되었지만 아직 메모리에 올라가진 않은 상태이다. 자원이 할당되면 (메모리 공간에 올라간다면) Ready 상태가 된다.
Ready 프로세스가 실행가능한 상태이다.
Running 프로세스가 실행되고 있는 상태이다.
Blocked I/O 작업이나 기타 메세지 통신 등 Timeout이 아닌 다른 이유에 의해 중단될 경우 Block 상태가 된다.
Exit 프로세스가 종료된 상태이다. 부모 프로세스 또는 OS가 종료를 확인하기 전까지 Exit 상태로 존재한다.

PCB가 생성되어 New 상태로 있는 프로세스는 자원이 할당되면(Admit) Ready 상태로 바뀐다.

Ready큐에 들어간 프로세스는 Dispatcher에 의해 선택되어 실행된다(Dispatch).

Running 상태에서는 정상적으로 실행하다가 정해진 CPU 반납 시간이 되었다면 다시 Ready큐로 돌아간다(Timeout). Timeout이 아니라 I/O 등 다른 이유에 의해서라면 Blocked 상태가 된다(Event Wait). Blocked 상태에서 기다리고 있다가 이벤트가 처리되었다면 다시 Ready 상태로 돌아간다(Event Occurs).

이렇게 Ready-Running-Blocked을 오가며 진행되다가 프로그램의 실행이 종료된다면 Exit 상태로 변하여 모든 자원을 반납하고 종료되기를 기다린다(Release). 그 프로세스를 만든 부모 프로세스 또는 OS가 종료를 확인하여야만 완전히 프로세스가 삭제된다.

Needs for Swapping

Dispatcher는 메모리에 올라와 있는 프로세스들을 실행시킨다. 그러나 모든 프로세스의 상태가 Blocked라면, Dispatcher는 실행시킬 수 있는 프로세스가 없고 CPU는 놀게 된다. 만약 메모리에 올라와 있지 않은 프로세스를 실행시킬 수 있다면 CPU를 최대한 활용할 수 있을 것이다.

가상 메모리 구조에서는 하드디스크에 프로세스가 존재할 수 있다. 위와 같은 상황에서 메모리에 있는 프로세스와 하드디스크에 있는 프로세스를 교체하면 메모리에는 다시 실행 가능한 프로세스들이 존재하므로 프로그램을 실행할 수 있다. 이를 Swapping이라고 부른다.

Swapping이 일어나는 이유는 대부분 I/O 작업이 CPU보다 느리기 때문에 프로세스가 Blocked된 상태로 존재하는 시간이 정말 길기 때문이다.

Seven state

가상 메모리 구조에서는 하드디스크에 프로세스가 존재할 수 있으므로 프로세스가 메모리에 있을 수도, 하드디스크에 있을 수도 있다. 즉 Ready 상태와 Block 상태가 프로세스의 현재 위치에 따라 두 가지로 나뉘어 존재한다.

프로세스가 생성되어 New 상태로 존재할 때 메모리에 올라갈 수도, 하드디스크에 올라갈 수도 있다. 메모리가 꽉 차서 더 프로세스를 올릴 수 없을 때에는 하드디스크에 프로세스를 올리게 된다. 이 때에는 Ready/Suspend 상태가 된다. 이 상태에 있는 프로세스들은 Swapping에 의해 메모리로 올라오게 되어 Ready 상태가 된다(Activate).

Blocked된 프로세스가 Swapping되어 하드디스크로 가게 된다면 Blocked/Suspend 상태가 된다(Suspend). Suspend된 프로세스들 중 OS가 생각했을 때 금방 Blocked 상태에서 벗어날 것 같은 프로세스들은 Ready/Suspend 상태의 프로세스들과 함께 하드디스크에서 메모리로 올라오게 된다(Activate).

Blocked/Suspend 상태에서 I/O 작업이 완료되어 Blocked상태가 해제된다면 Ready/Suspend 상태가 된다(Event Occurs). (여전히 하드디스크에 있기 때문에 Suspend가 붙는다.)

Q. 큐 안에는 실제 프로세스가 들어가나?

앞에서 Swapping을 얘기할 때에는 실제로 프로세스가 하드디스크로 이동한다. 그러나 단순 프로세스의 상태가 변하는 것은 한 큐에서 다른 큐로 프로세스의 포인터가 이동하는 것이다. 프로세스의 크기가 굉장히 큰데 그 데이터를 전부 큐에 이동시킨다고 생각하면 읽고 쓰는 작업이 엄청날 것이다.

Suspension

프로세스가 Suspend 되는 이유는 다양하다.

이유 상태변화
OS가 메모리를 확보하기 위해 Ready/Suspend → Ready, Blocked → Blocked/Suspend
사용자와 상호작용이 없는 프로세스들 또는 문제를 일으키고 있다고 의심되는 프로세스들이 있을 때 Ready → Ready/Suspend
유저 프로그램이 시스템 함수 Pause 등을 호출하여 실행 중간에 프로세스를 Suspend할 때 Running → Ready/Suspend
일정 시간마다 실행되므로, 다음 주기 전까지는 메모리에 없어도 될 때 Running → Ready/Suspend
부모 프로세스가 실행 중에 자식 프로세스의 상태를 변경할 때 Ready → Ready/Suspend

Process Description

OS는 시스템의 모든 자원 그리고 모든 프로세스를 관리하는 임무를 가진다. 효율적으로 관리하기 위해서 모든 자원들을 테이블 형태로 관리한다.

Memory table

  • 메모리 또는 하드디스크에 할당된 프로세스의 정보
  • 공유 메모리에 대한 정보
  • 가상 메모리에 대한 정보

I/O table

  • 할당되거나 사용가능한 I/O 장치
  • I/O 장치의 상태
  • 현재 I/O 장치가 메인 메모리의 어느 위치와 입출력하고 있는 지에 대한 정보

File table

  • 파일의 존재 유무
  • 하드디스크에서 파일의 위치
  • 파일이 열렸는지, 파일 포인터의 위치 등의 정보

Primary Process table

프로세스에게는 이 테이블의 정보가 중요하다.

  • Process ID (PID)
  • 프로세스 이미지에 대한 포인터
  • 메모리에 있는지 하드디스크에 있는지에 대한 정보

Process Control Block

프로세스 이미지에는 User Data, User Program, Stack 그리고 PCB가 존재한다. PCB는 3가지 종류의 데이터를 갖고 있다.

Process Identification

프로세스 테이블에 대한 인덱스들이다.

정보 설명
Process Identifier (PID) 프로세스 테이블에서 프로세스의 인덱스
Parent Process Identifier (PPID) 프로세스를 만든 부모 프로세스의 PID
User Identifier (UID) 실행을 시킨 사람이 누구인지

Processor State Information

CPU의 레지스터값들이다. Interrupt가 일어나면 Control Stack에 저장된다.

  • General Register
  • Program Counter
  • Program Status Word
  • Stack Pointers

Process와 Processor를 헷갈려 하는 경우가 있으므로 주의하자.

Process Control Information

프로세스 관리에 필요한 정보들이다.

정보 설명
Scheduling and State information 프로세스의 상태 및 스케줄링 정보
Memory management 세그먼트 및 페이지에 대한 정보
Resource ownership and Utilization 생성한 동기화/메세지 큐 자원에 대한 정보, 하드웨어에 대한 정보
Inter-process Communication 프로세스 간 통신에 사용된 정보들
Process Privileges 프로세스에게 할당된 메모리나 하드웨어 자원에 대한 권한
Data Structuring 다른 프로세스와의 관계를 나타내는 자료구조에 대한 정보

PCB는 프로세스 이미지에서 아래 사진처럼 존재한다.

Private User Address Space는 말 그대로 유저만의 영역으로 프로그램 코드와 데이터들이 들어있다.

Shared Address Space는 다른 프로세스와 같이 사용하는 데이터 영역이다. 물리적으로는 프로세스 영역 밖에 존재하지만 프로세스의 단위로 보면 같이 묶인다.

Kernel with process

프로세스를 관리하는 커널은 다음과 같은 임무를 수행한다.

  • 프로세스 생성/종료
  • 프로세스 스케줄링 및 실행, 프로세스 간 우선순위 설정
  • 프로세스 스위칭
  • 프로세스 간 통신을 위한 도구 및 동기화 도구 제공
  • 프로세스의 PCB 수정
  • 프로세스에게 자원 할당
  • 프로세스 Swapping
  • 페이지 및 세그먼트 관리
  • Interrupt Handling
  • ...

Process Creation

프로세스의 생성과정은 다음과 같다.

  1. 새 프로세스에게 PID를 할당한다.
  2. 프로세스에게 메인 메모리 또는 HDD Swapping 메모리를 할당한다. 메모리를 할당한다는 것은 프로세스 이미지가 메모리에 올라왔다는 것을 말한다. 그 이미지 속에 프로그램 데이터와 코드를 넣고, 스택을 초기화한다.
  3. 프로세스의 PCB를 초기화한다.
  4. 스케쥴링 큐에 이미지의 링크(포인터)를 연결한다. Ready 또는 Ready/Suspend에 프로세스의 포인터가 삽입된다.
  5. 기타 프로세스 테이블이나 프로세스 트리 등에 PID를 추가한다.

프로세스의 삭제는 위 과정의 역순으로 진행된다.

Process Switching

실행 중인 프로세스가 중단되고 다른 프로세스를 실행해야할 때 프로세스 스위칭이 일어난다.

발생 상황

Interrupt가 발생할 때 프로세스의 상태가 변하는데 이 때 스위칭이 일어난다. 그러나 Interrupt의 종류에 따라 상태가 다르게 변한다.

Interrupt = 외부 요인으로 방해(interrupt)를 받은 것
Trap = 현재 명령어 실행으로 발생, 프로그램이 원인인 것

Interrupt는 외부에서, 즉 I/O 작업 완료Timeout, 또는 Hardware Failure 같이 프로그램 외적인 이유 때문에 발생한 것을 말한다. 반대로 Trap은 현재 실행하는 프로그램의 명령어가 잘못 실행되어 문제가 발생한 것이다.

  • Interrupt

    • Timeout (→ Ready)

    • I/O (→ Running / Ready)

      I/O Interrupt는 I/O 작업을 요청한 프로세스가 실행중일 때 일어나는게 아니라 무관한 프로세스가 실행되는 중에 일어난다. Interrupt가 끝난 후 곧바로 이어서 실행되거나(Running) 다시 Ready 상태로 돌아갈 수 있다.

    • Memory fault (→ Blocked)

      메모리에 특정 데이터가 없어 HDD에서 읽어와야 할 때 I/O 요청을 하게 된다. 프로그램 실행이 불가능하기 때문에 I/O 작업이 완료되기 전까지 Blocked 상태로 간다.

  • Trap (→ Exit / Running)

    프로그램이 실행 중에 잘못한 경우, 실행될 수 없어서 종료된다. 그러나 OS가 별 문제삼지 않는 경우에는 그대로 실행할 수도 있다.

  • Supervisor Call (→ Blocked)

    유저 프로그램이 OS 함수를 호출한다. 입출력 작업, 동기화, 프로세스 간 통신이 대부분이므로 그런 작업이 끝날 때까지 Blocked 상태가 된다. 간단한 요청들은 금방 끝나므로 Running 상태가 유지된다.

Execution mode

프로세스는 두 가지 모드중 하나인 상태로 실행된다.

  • User mode : 제한된 모드로 유저 프로그램이 실행될 때 이 모드로 실행된다.
  • Kernel mode : 모든 권한을 갖고 커널 프로그램이 실행된다.

유저 프로그램이 실행되다가 커널 프로그램이 실행될 때 두 가지의 스위칭 상황이 발생한다.

  • Mode switching : User mode(A) → Kernel mode -> User mode(A)

    프로세스가 바뀌지는 않지만, 중간에 커널 모드로 실행되는 경우이다.

  • Process switching : User mode(A) → Kernel mode -> User mode(B)

    커널 모드를 거치면서 프로세스가 바뀌는 경우이다.

Context Switching과 헷갈리지 말자. Context Switching은 현재 실행중인 프로세스에서 다른 프로세스로 교체하는 과정이다.

Change of Process state

프로세스 스위칭의 과정은 다음과 같다.

  1. CPU의 레지스터값들을 현재 프로세스의 Processor State Information에 저장한다.
  2. Process Control Information을 업데이트한다.
  3. 프로세스의 상태를 변경하기 위해 적절한 큐로 이동시킨다.
  4. 다음에 실행할 프로세스를 결정한다.
  5. 실행할 프로세스의 Process Control Information을 업데이트한다.
  6. 실행할 프로세스의 Page table을 업데이트한다. (Reallocation, Protection 등)
  7. 실행할 프로세스의 Processor State Information을 CPU의 레지스터로 불러온다.

Execution of Operating System

옛날에는 OS 프로그램 즉, 커널을 메모리에 모두 올렸으므로 고정된 위치에 커널을 올렸다. 그러나 커널이 거대해짐에 따라 쪼개질 수 밖에 없게 되었고, 정말 필요한 코드들만 메모리에 상주시키게 되었다.

유저 프로세스 속에 커널 코드

유저 프로세스가 호출할 수 있는 커널 코드들이 유저 프로세스 속에 들어있다. 이렇게 하면 프로세스 스위칭없이 그냥 모드만 바꿔서 실행하면 되므로 Context Switching이 없다.

이 방법을 사용하려면 위 사진처럼 프로세스 속에 커널 코드와 커널 스택을 갖고 있어야 한다. 유저 프로그램을 실행할 때에는 User mode로, 커널 코드를 실행할 때에는 Kernel mode로 동작하게 된다.

객체지향

OS를 프로세스로 취급하여 객체지향 디자인을 적용한다. 이렇게 하면 확장성이 올라간다.

위 사진에서 OS로 표시된 프로세스들은 OS 코드를 갖는 프로세스 이미지들이다. 이 방법은 마이크로커널을 사용한다.

UNIX SVR4

UNIX는 유저 프로세스 속에 커널 코드를 갖는 방법을 사용한다. 대부분의 커널 코드들이 유저 프로세스 속으로 들어갈 수 있지만 정말 기본이 되는 Swapper 프로세스나 모든 프로세스의 조상인 init 프로세스 등 시스템 작업을 하는 코드들은 별도의 커널 프로세스로 분리되어 동작한다.

Process description

UNIX에서 프로세스의 정보들은 이름이 약간 다르게 분류된다.

  • User Level Context
    • 프로그램 코드
    • 프로그램 데이터
    • 유저 스택
    • 공유 메모리
  • Register Context
    • Program Counter
    • Processor Status Register
    • Stack Pointer
    • General-purpose Register (CPU의 일반적인 레지스터들)
  • System Level Context
    • Process table entry
    • U area
    • Per process region table
    • Kernel Stack

State transition diagram

UNIX의 프로세스 상태도는 아래 사진과 같다.

9가지나 되는 상태가 존재하지만, 아래 사진과 같이 묶어보면 7개의 상태도와 유사하다.

User Running 상태와 Kernel Running 상태가 같이 존재한다. 왜냐하면, UNIX에서 유저 프로세스 내에 커널 코드와 커널 스택이 존재하기 때문이다.

UNIX에서는 새로운 프로세스를 생성할 때 이미 존재하는 프로세스를 fork하는 방법으로 만든다. 어쨌든 프로세스가 생성되고 나서는 메인 메모리에 올리려고 하는데 메인 메모리가 꽉 찼다면 하드디스크에 올린다(Ready to Run Swapped).

메인 메모리에 올라왔다면 Ready to Run In Memory 상태가 된다. 프로세스를 실행하게 된다면 Kernel Running 상태를 거치게 되는데, 항상 유저 프로그램 실행 전에 OS가 작업을 한다는 의미이다. Kernel Running 상태에서는 OS가 몇 가지 작업을 한 뒤 User Running 상태로 전환되어 유저 프로그램을 실행한다.

유저 프로그램 실행 중에 Interrupt가 발생하거나 System call을 할 때에는 다시 Kernel Running 상태로 변경되어 OS 작업을 수행한다. 간단한 OS 작업을 수행한다면 곧바로 User Running 상태로 돌아가게 된다(return).

유저 프로그램 실행중에 Timeout이 걸리게 된다면, 일단 Kernel running 상태에서 곧바로 Preemted 상태(선점당함)로 바뀐다. Preemted 상태는 Ready to Run In Memory 상태와 점선으로 이어져 있는데 둘 다 프로세스가 Ready 큐에 존재한다는 의미이다. 그러나 Preemted 상태는 Kernel Running을 거치지 않고 User Running 상태로 향할 수 있다.

Q. 커널 모드를 거쳐야 유저 프로그램을 실행하도록 설계되었는데 왜 곧바로 Preemted에서 User Running으로 바뀔 수 있을까?

OS가 Timeout시킨 프로세스를 다시 실행할 때에는 메모리 관리같은 작업을 별도로 거치지 않아도 된다. 메모리에 할당된 그 자리에서 그대로 유지하고 있기 때문에, 프로세스를 실행하기 전에 거쳐야 할 작업을 하지 않고 실행이 가능하다. 반대로 Ready to Run In Memory 상태는 New/Swapped/Blocked 상태였던 프로세스들이 실행되기를 바라는 상태이므로 OS가 필요한 정보들을 업데이트해야 한다.

사실 명확한 이유를 찾기 힘들었다.

프로세스가 Blocked 상태로 바뀌어야 한다면 User Running에서 Kernel Running으로 상태를 변경한 다음 OS 작업을 거친 후에 Asleep in Memory 상태로 변한다. 이 상태에서 다시 Blocked 상태가 해제된다면 프로세스가 깨어나서 다시 Ready to Run In Memory 상태로 바뀐다(wakeup).

7개 상태도에서 프로세스는 메모리에서 하드디스크로 swapped 될 수 있다. UNIX에서도 동일하게 swapped 될 수 있는데, Ready to Run In Memory는 swap-in, swap-out의 양방향 화살표가 있지만 Asleep in Memory에서는 swap-out밖에 보이지 않는다.

Blocked 상태로 바뀐 프로세스가 Swapped 되었다면 무조건 Blocked 상태가 해제되어야 다시 메모리로 올라올 수 있도록 설계한 것이다.

댓글