[OS] 5. 프로세스란?

KYJ의 Tech Velog·2023년 4월 12일
0

OS

목록 보기
6/23
post-thumbnail

프로세스 (Process)

프로세스는 실행 중인 프로그램(Program In Execution)을 의미합니다. 프로그램은 하드디스크(보조기억장치)에 저장되어 아무 일도 하지 않는 상태입니다.

프로그램을 어떠한 요청에 의해 메인 메모리에 할당하여 CPU를 사용하면서 실행하게 되면 이를 프로세스로 부릅니다. Job, Task라고도 부릅니다.


프로세스의 생성과 종료

프로세스는 프로세스의 의해 만들어집니다. 컴퓨터가 부팅이 되면 운영체제가 메모리에 올라오고 운영체제가 처음으로 수행하는 일 중에 하나는 최초의 프로세스를 생성하는 것입니다. 이 프로세스가 다른 프로세스를 만들고 그 프로세스가 또 다른 프로세스를 만드는 과정을 반복합니다.

UNIX 운영체제 기준으로 최초의 프로세스의 이름은 Init입니다.

프로세스들이 다양하게 생성되면 프로세스를 생성한 쪽을 부모 프로세스, 생성된 프로세스를 자식 프로세스라고 합니다. 같은 부모 프로세스를 가진 자식 프로세스는 형제 프로세스라고 합니다.

프로세스 생성

새로운 프로세스를 만드는 시스템 콜은 fork()입니다.

생성된 프로세스에서 어떤 파일을 실행하려면 시스템 콜 exec()를 사용합니다.

프로세스 종료

프로세스를 종료하는 시스템 콜은 exit()입니다. 프로세스가 종료되면 사용한 모든 자원을 회수해서 운영체제로 돌아가야합니다.


프로세스 상태

  • New
    프로그램이 메인 메모리에 할당
  • Ready
    할당된 프로그램이 초기화와 같은 작업을 통해 실행되기 위한 준비를 마침
  • Running
    CPU가 해당 프로세스를 실행
  • Blocked(Waiting)
    프로세스가 I/O 작업 등을 처리 중인 상태
    프로세스가 외부 이벤트를 기다리는 상태
  • Terminated
    프로세스가 완전히 종료

프로세스 상태 전이

  • new -> ready
    new 상태에서 프로세스가 생생되게 되면 운영체제 커널에 존재하는 Ready Queue에 올라가게 됩니다.
  • reday -> running
    Ready Queue에 있는 프로세스들을 운영체제가 프로세스 스케줄링 알고리즘에 의해서 실행할 프로세스를 CPU로 할당합니다.
  • running -> ready
    현재 실행중인 프로세스보다 Ready Queue에 대기하고 있는 프로세스가 우선순위가 높다면 선점형 스케줄링을 알고리즘을 사용할 경우 전자의 프로세스를 Ready 상태로 바꾸고 후자의 프로세스를 CPU를 할당합시켜 실행합니다.
  • running -> blocked
    현재 실행중인 프로세스가 I/O 이벤트가 발생했을 때 Blocked 상태로 전이됩니다.
  • blocked -> ready
    I/O 이벤트가 종료된 프로세스는 다시 Ready 상태로 전이됩니다.
  • running -> waiting
    현재 실행중인 프로세스가 외부 이벤트를 기다려야 할 때 Waiting 상태로 전이됩니다.
  • waiting -> ready
    외부 이벤트가 종료되면 다시 Ready 상태로 전이됩니다.
  • running -> terminate
    프로세스가 종료되면 Terminate상태로 전이됩니다.

프로세스의 구성

PCB (Process Control Block)

프로세스에 대한 모든 정보는 PCB라고 부르는 자료구조에 저장됩니다. 이 자료구조는 다음과 같은 정보를 가지고 있습니다.

  • PID
    프로세스 식별 번호 (Process IDentification)
  • 프로세스 상태
  • 프로그램 카운터
    프로세스가 다음에 실행할 명령어의 주소
  • CPU 레지스터 및 일반 레지스터
  • CPU 스케줄링 정보
    우선 순위, 최종 실행시각, CPU 점유 시간 등
  • 메모리 관리 정보
    프로세스의 주소 공간 등
  • 프로세스 계정 정보
    페이지 테이블, 스케줄링 큐 포인터, 소유자, 부모 등
  • 입출력 상태 정보
    프로세스에 할당된 입출력장치 목록, 열린 파일 목록 등
  • 포인터
    부모/자식 프로세스에 대한 포인터, 프로세스가 위치한 메모리 주소에 대한 포인터, 할당된 자원에 대한 포인터 정보 등

Context Switching

Context Switching은 프로세스가 실행되다가 인터럽트가 발생해 CPU를 한 프로세스에서 다른 프로세스로 넘겨주는 과정입니다.

운영체제는 CPU를 내어주는 프로세스의 상태를 그 프로세스의 PCB에 저장하고, 새롭게 CPU를 얻는 프로세스의 상태를 PCB에서 읽어옵니다. 즉, PCB 정보가 바뀌는 것이 Context Switching입니다.

다만, 시스템 콜이나 인터럽트가 발생한다고 반드시 Context Switching은 아닙니다. 다른 프로세스에 CPU가 넘어가야 Context Switching입니다.


프로세스 스케줄링

CPU 스케줄링이라고도 합니다.

멀티프로그래밍(Multiprogramming)의 목적은 CPU를 최대한 사용하기 위해 여러 개의 프로세스를 항상 실행시키는 것입니다.

시간 공유(Time Sharing)의 목적은 프로세스 간에 CPU를 빠르게 전환함으로써 사용자가 각 프로그램이 실행되는 동안 서로 상호작용할 수 있도록 만드는 것입니다.

이러한 목적들을 당성하기 위해 프로세스 스케줄러는 CPU에서 프로그램 실행을 위해 사용 가능한 프로세스를 선택합니다. 이렇게 어떤 프로세스를 CPU에 할당할 것인가를 결정하는 일을 프로세스 스케줄링(Process Scheduling)이라고 합니다.

CPU가 하나인 시스템은 하나의 running 프로세스를 가질 수 있고, 여러 프로세스가 존재하는 경우 나머지 CPU가 free 상태가 될 때까지 대기해야 하기 때문에 적절한 스케줄링이 필요합니다.

프로세스를 스케줄링하기 위한 자료구조로 Queue를 사용합니다.

프로세스 큐(Queue)

프로세스는 실행되면서 상태가 여러 번 변하게 됩니다. 변한 상태에 따라서 서비스를 받아야 하는 곳이 다릅니다. 그리고 일반적으로 프로세스는 여러 개가 한 번에 실행되므로 실행되는 순서가 필요합니다.

  • Job Queue
    하드 디스크에 있는 프로그램이 실행되기 위해 메인 메모리의 할당 순서를 기다리는 Queue
  • Ready Queue
    CPU 점유 순서를 기다리는 Queue
  • Device Queue
    I/O를 하기 위한 여러 장치가 있는데 각 장치를 기다리는 Queue

스케줄러는 3가지 종류가 있습니다.

  • Long-Term Scheduler (장기 스케줄러 or Job Scheduler)
    시작 프로세스 중 어떤 프로세스를 Ready Queue로 보낼지 결정하고 프로세스에 메모리 및 각종 자원을 할당합니다. 자주 발생하지는 않습니다. Degree of Multiprogramming(메모리의 몇 개의 프로세스가 존재)을 제어합니다.
    Time-Sharing 시스템에서는 보통 Long-Term Scheduler가 존재하지 않고 무조건 Ready Queue로 올라가는 방식입니다.
  • Short-Term Scheduler (단기 스케줄러 or CPU Scheduler)
    어떤 프로세스를 다음에 실행시킬지를 선택하고 프로세스에 CPU를 할당합니다.
  • Medium-Term Scheduler (중기 스케줄러 or Swapper)
    프로세스를 수행하다가 메모리에서 잠시 제거했다가 시간이 지난 후 다시 메모리에 넣고 수행을 이어나가는 것이 더 이득이 될 수 있는 경우가 존재합니다. 프로세스를 통째로 메모리에서 디스크로 쫓아내서 여유 공간을 마련하는 작업을 Swapping이라고 합니다. Degree of Multiprogramming을 제어합니다.

현대 OS는 거의 단기 스케줄러를 사용합니다. 나중에 포스팅할 가상 메모리 덕분에 단기 스케줄러 만으로도 OS가 정상적으로 작동할 수 있습니다.


좀비 프로세스 & 고아 프로세스

좀비 프로세스

자식 프로세스가 부모 프로세스보다 먼저 종료되는 경우에 자식 프로세스를 좀비 프로세스라고 합니다. 자식 프로세스가 exit() 시스템 콜을 호출하면서 종료되면 이 프로세스에 관련된 모든 메모리와 자원이 해제되어 다른 프로세스에서 사용할 수 있게 됩니다.

자식 프로세스가 부모 프로세스보다 먼저 죽는 경우, 부모 프로세스가 종료 상태를 회수하기 위해 커널은 자식 프로세스의 최소한의 정보(PID, 종료 상태 등)를 가지고 있게 됩니다. 부모 프로세스가 좀비 프로세스의 종료 상태를 회수하게 되면(wait() 시스템 콜 호출) 좀비 프로세스는 제거됩니다.

커널 입장에서 좀비 프로세스는 최소한의 정보를 가지고 있기 때문에 큰 성능 저하를 야기하지는 않습니다. 하지만 프로세스 스케줄링에 있어서 queue에 대기하고 있는 프로세스의 양이 증가하게 되고, 커널 구조체를 유지하기 위한 비용도 무시할 수는 없습니다.

고아 프로세스

부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우에 자식 프로세스를 고아 프로세스라고 합니다. 이 때, 초기 프로세스(init())가 이 고아 프로세스의 새로운 부모 프로세스가 됩니다.

종료되는 프로세스가 발생할 때, 커널은 이 프로세스가 누구의 부모 프로세스인지 확인하고 이 고아 프로세스의 부모 프로세스 ID를 1(init 프로세스)로 바꿔줍니다. 고아 프로세스가 작업을 종료하면 init 프로세스가 wait()을 호출하여 고아 프로세스가 좀비 프로세스가 되는 것을 방지합니다.

고아 프로세스는 init 프로세스가 관리를 해 주지만 부모 프로세스가 종료되기 전에 모든 자식 프로세스를 wait() 처리 해주는 것이 좋습니다.

0개의 댓글