process creation

실행되는 동안 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다. 생성하는 프로세스를 부모 프로세스라고 부르고, 새로운 프로세스는 자식 프로세스라고 부른다. 이 새로운 프로세스들은 각각 다시 다른 프로세스들을 생성할 수 있고, 그 결과 트리 형태를 가진다.


현대 운영체제들은 PID를 사용하여 프로세스를 구분하는데 이 식별자는 보통 정수이다. PID는 시스템의 각 프로세스에 고유한 값을 가지도록 할당한다.

기존의 UNIX 시스템은 init 프로세스를 모든 자식 프로세스의 루트로 식별한다. 하지만 그림 3.7에는 systemd가 PID 1을 가지는걸 볼 수 있다. 이는 현재 Linux 시스템에서 system V init 방식이 아니라, 좀 더 발전된 형태인 systemd로 대체하여 사용하는데, 이를 반영한 그림이다.


일반적으로 프로세스가 자식 프로세스를 생성할 때, 그 자식 프로세스는 자신의 task를 달성하기 위하여 자원(CPU 시간, 메모리, 파일, 입출력 장치)이 필요하다.

자식 프로세스는 이 자원을 운영체제로 부터 직접 얻거나, 부모 프로세스가 가진 자원의 부분 집합만을 사용하도록 제한될 수 있다.

부모 프로세스는 자원을 분할하여 자식 프로세스들에게 나누어 주거나 메모리나 파일과 같은 몇몇 자원들은 자식 프로세스들이 같이 사용하게 할 수도 있다.

새로운 프로세스는 fork() system call로 생성된다. 이는 원래 프로세스의 address space의 복사본으로 구성된다. 이 기법으로 부모가 자식 프로세스와 쉽게 통신할 수 있다. fork()를 통해 자식 프로세스가 생성되는데, 이때 fork함수의 return 값은 부모는 자식 프로세스의 PID를 가지고, 자식은 0을 return 받게 된다.

process termination

프로세스가 마지막 문장의 실행을 끝내고, exit system call을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다. 이때 자식 프로세스는 자신을 기다리고 있는 부모 프로세스에 (wait system call을 통해) 상태 값을 반환할 수 있다.
이때 부모 프로세스는 자식 프로세스의 PID를 통해 자식 프로세스를 종료시킬 수 있다.
몇몇 시스템에서는 부모 프로세스가 종료한 이후에 자식 프로세스가 존재할 수 있다. 그러한 시스템에서는 프로세스가 종료되면(정상적이든 비정상적이든) 그로부터 비롯된 모든 자식 프로세스들도 종료되어야 한다. 이것을 cascading termination 이라고 부르며 이 작업은 운영체제가 시행한다.
프로세스가 종료하면 사용하던 자원은 운영체제가 되찾아 간다. 그러나 프로세스의 종료 상태가 저장되는 프로세스 테이블의 해당 항목은 부모 프로세스가 wait()를 호출할 때까지 남아있게 되는데, 이를 좀비 프로세스라고 한다. wait()을 호출하지 않은 채로 부모가 죽어버리면 고아 프로세스가 된다. UNIX에서는 고아 프로세스는 init 프로세스로 새로운 부모를 지정한다.

exit호출로 종료된 프로세스는 자신의 부모프로세스가 종료되거나 wait(2) 계열의 함수를 이용해서 프로세스가 정리될때까지 “좀비(zombie)” 상태로 남아있게 된다. 좀비프로세스는 이미 프로세스가 exit 한상태이기 때문에, 메모리나, 파일디스크, cpu 자원을 소모하지는 않는다. 그러나 task_struct 구조체를 소비하게 됨으로, 많은 수의 좀비프로세스는 시스템에 악영향을 끼칠수 있다.