부모 프로세스가 연산을 통해 자식 프로세스를 트리구조로 생성합니다.
생성된 자식 프로세스 또한 부모 프로세스가 되어 새로운 자식 프로세스를 생성할 수 있습니다.
각 프로세스를 각각 식별하고 관리하고 위하여 고유의 PID(Process Identifier) 를 가지게 됩니다.
부모 프로세스와 자식 프로세스 사이의 자원 공유 옵션
자식 프로세스 생성 후, 부모 프로세스의 행동
자식 프로세스의 주소 공간
fork()
Linux/UNIX 환경에서 새로운 프로세스를 만드는 시스템 콜 함수입니다.
생성된 자식 프로세스는 부모 프로세스의 데이터와 프로그램이 완전히 복사가 되어 똑같은 프로그램을 수행하는 프로세스가 됩니다.
fork() 함수는 부모 프로세스에서 자식의 PID를 반환하고, 자식 프로세스에서는 0을 반환하여 구분할 수 있도록 해 줍니다.
exec()
Linux/UNIX 환경에서 프로세스를 새로운 프로그램을 실행하는 프로세스로 대체하는 시스템 콜 함수입니다.
프로그램 코드, 메모리, 파일 등 프로세스 자원이 새로 바뀌게 됩니다.
exec() 함수는 현재 프로세스가 완전히 새로운 프로그램을 실행하는 프로세스로 대체되므로 반환 값이 없습니다.
wait()
자식 프로세스가 종료될 때까지 현재 프로세스의 동작을 멈추는 시스템 콜 함수입니다.
자식 프로세스가 종료되면 자식 프로세스 종료 시그널(SIGCHLD → Signal Child)이 발생하여 waiting queue에 있는 부모 프로세스가 ready queue로 넘어가게 되어 다시 실행이 가능해집니다.
exit()
현재 프로세스가 종료되어 SIGCHLD 시그널이 부모 프로세스로 전달되고, wait() 된 부모 프로세스는 자식 프로세스의 exit() 함수에 의해 정상 종료가 됨을 알 수 있습니다.
함수 호출 후, 자식 프로세스에 할당된 모든 자원은 OS에 의해 할당 해제됩니다.
exit() 함수가 없더라도, 프로그램 코드의 끝에 도달하거나 return 키워드를 만나게 되면 자동으로 exit() 함수가 호출됩니다.
abort()
해당 함수를 호출한 프로세스에 SIGABRT 시그널을 보냅니다. SIGABRT 시그널은 프로세스를 비정상적으로 종료시키고 코어 덤프 파일을 생성합니다.
부모 프로세스가 자식 프로세스를 강제 종료 시키는 경우
좀비 프로세스
자식 프로세스가 부모 프로세스보다 먼저 죽는 경우 부모 프로세스가 종료 상태를 회수하기 위해 커널이 자식 프로세스의 최소한의 정보(PID, 종료 상태 등) 를 남겨둡니다.
부모 프로세스는 wait 함수를 호출하여 이 상태를 회수하면 남은 모든 정보가 제거되어 자식 프로세스는 완전히 소멸하게 됩니다.
위와 같은 진행상황에서 부모 프로세스가 wait함수를 호출하지 않아 최소한의 정보가 메모리에남아있는 경우를 좀비 프로세스라고 합니다.
고아 프로세스
부모 프로세스가 자식 프로세스보다 먼저 종료되는 경우 부모 프로세스가 없는 자식 프로세스를 말합니다.
운영체제는 이러한 고아 프로세스를 허용하지 않으며 부모 프로세스가 먼저 종료되면 자식 프로세스의 새로운 부모 프로세스로 init(PID = 1)가 설정됩니다.
init 프로세스는 자식 프로세스가 종료될 때까지 기다린 후 wait 함수를 호출하여 고아 프로세스의 종료 상태를 회수하여 좀비 프로세스가 되는 것을 방지합니다.
고아 프로세스는 프로세스 자신이 시스템의 자원을 낭비할 수 있고, 시스템이 프로세스가 종료될 때까지 추적을 해야 하기 때문에 성능 저하의 원인이 됩니다.