본문 바로가기

Computer Science/Computer Systems

[Lecture 1-3] Processes Part III

#Process Management

OS 는 process들을 관리 하기 위해 API (system calls)들을 제공한다. 프로세스를 관리 하기위해선 여러가지의 단계가 필요하다. 

 

Process Creation: 프로세스를 생성하는 단계이다, 보통 프로세스의 새로운 환경을 생성하는 것을 포함한다.

 

Process Termination: 이단계는 일반적인 프로세스 종료와 비정상적 프로세스종료를 포함한다. 일반적이 프로세스 종료 (Normal termination) 은 main() 함수에서 return된 exit() 함수같은 것이고, 비정상적 종료 (Abnormal termination) 은 보통 예상치못한 crash나 외부 개입에 의해 프로세스가 "kill" 된상태이다

 

Process interaction: 프로세스 상호작용은 하나의 프로세스가 다른 프로세스가 끝나길 기다리거나, 하나의 프로세스를 멈추거나/다시 시작시킬때 발생한다. 

 

이외에도 프로세스 속성이나 스케링 (scheduling) 바꾸기, 보고 및 프로파일링 기능 등등이 있다. 또한 OS는 제어 프로그램에서 사용하거나 제어 프로그램 (Shell, GUI, Task Manager 등등)과 연계하여 사용할 수 있는 기능을 제공한다.

 

#Windows Example

Process create 단계의 대표적인 예는 윈도우의 CreateProcessA 가있다.

BOOL CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

이 단계에서는 process를 생성 ("spawn")하고 인수 (argument) 와 속성 (attribute)을 가진 새 프로그램을 실행하도록 지시한다.

#Unix Example

Unix는 프로세스 생성과 새 프로그램 로드를 분리한다.  예를 들어, fork() 시스템 호출은 새 프로세스를 생성하지만 새 프로그램을 로드하지 않는다. Unix의 프로세스들은 트리 같은 계층을 생성하기때문에, 새로 생성된 프로세스를 하위 (child) 프로세스라고 하고, 생성 프로세스를 상위 (parent) 프로세스라고 한다.하위 프로세스는 부모로부터 환경의 일부를 상속받을 수 있지만 그렇지 않으면 별개의 개체로 분리된다. 그러면 하위 프로세스가 환경을 변경/설정하고 준비가 되면 현재 프로그램을 대체하지만 환경의 특정 측면을 유지하는 새 프로그램을 로드한다 (exec()). 부모에게는 자식 프로세스가 종료될 때까지 대기(wait()를 통해)하는 옵션이 있으며, 이를 자식 프로세스에 "참여 (joining)"라고도 한다. 부모 프로세스가 자녀 프로세스가 종료된 방식도 배울 수 있다. (예: child process가 exit()에 전달한 코드).

 

#fork() vs exec()

fork() 와 exec() 모두 새 프로세스를 만들고 시작하는 데 사용되는 시스템 호출이다. fork() 와 exec()의 주요 차이점은 fork()는 현재 호출 프로세스의 복제를 생성함으로써 새로운 프로세스를 생성하는 반면, exec()는 전체 호출 프로세스를 완전히 새로운 프로그램으로 대체한다는 것이다.

fork():

  • 프로그램과 프로세스를 유지하지만 새 프로세스도 생성함
  • 새 프로세스는 상위 프로세스의 복제본임. 하위 상태는 heap, stack, 파일 설명자 (file descripter) 등 모든 것을 포함한 상위 (parent) 상태의 복사본이다. 
  • fork() 는 한 번만 호출되고, 두 번 반환됨 (부모에 한 번, 자녀에 한 번)

exec():

  • 프로세스를 유지하지만 이전 프로그램은 폐기하고 새 프로그램을 로드함.
  • 프로세스 상태를 재초기화한다 (heap + stack 지우기, 새 프로그램의 main()에서 시작). 단, 파일 설명자를 유지한다.
  • 위 단계들이 성공하면 한 번 호출되지만 반환되지 않음
  • 여러 variants들을 포함함 (execvp() 등등)

fork/exec/exit/wait Diagram

#다양한 시나리오를 위한 유닉스 용어

  • zombies: 종료되었지만 상위가 아직 활성 상태이고 아직 대기하지 않은 프로세스임. 부모가 자신을 기다리거나("재배 ") 부모가 퇴장할 때까지 존재하게 된다.
  • Orphan & Daemon: 활성 상태이지만 부모가 대기하지 않고 종료한 프로세스이다.  초기화 프로세스(PID 1)에 재할당된다. 보통 의도하지 않은 경우이고, 의도된 경우, Orphan은 Daemon이라고도 불릴 수 있다.
  •  Run-Aways: 활성 상태이고 종료되지 않은 프로세스는 항상 준비/실행 중이기 때문에 예약 (scheduled)된 경우 유용한 작업을 수행하지 않고 CPU를 100% 사용함.