좀비(zombie) 프로세스란
-
프로세스가 종료 될 때, 마지막 문장의 실행을 끝내고,
exit()
시스템 호출을 사용하여 운영체제에게 자신의 삭제를 요청하면서 종료된다. -
이 시점에서, 프로세스는 자신의 부모가 호출한
wait()
시스템 호출을 통해서, 상태 값을 반환할 수 있고, 물리 메모리와 가상 메모리, 열린 파일, 입출력 버퍼를 포함한 프로세스의 모든 자원이 운영체제로 반납된다. -
부모 프로세는
wait()
시스템 호출을 사용하여 자식 프로세스가 종료할 때를 기다릴 수 있고, 부모가 자식의 종료 상태를 얻어 낼 수 있도록 하나의 인자를 전달 받는다. 이 시스템 호출은 부모가 어떤 자식이 종료되었는지 구별할 수 있도록 종료된 자식의 프로세스 식별자를 반환한다. -
프로세스가 종료되면 사용하던 자원은 운영체제가 되찾아가게 된다. 그러나 프로세스의 종료 상태가 저장되는 프로세스 테이블의 해당 항목은 부모 프로세스가
wait()
을 호출할 때까지 남아있게 된다. -
따라서 종료가 되었지만 부모 프로세스가 아직
wait()
호출을 하지 않은 프로세스를 좀비 (zombie
) 프로세스라고 한다. -
모든 프로세스는 종료하게 되면, 좀비 상태가 되지만 아주 짧은 시간 동안 머무르게 되고, 부모가
wait()
를 호출하면 좀비 프로세스의 프로세스 식별자와 프로세스 테이블의 해당 항목이 운영체제에게 반환된다.
고아 프로세스란(orphan)
- 좀비 프로세스와 비슷한 고아 프로세스라는 것이 있다.
- 고아 프로세스는 부모 프로세스가
wait()
을 호출하는 대신에 그냥 종료를 해버리는 것이다. 이러한 상황에 처한 자식 프로세스를 고아(orphan
) 프로세스라고 한다. - 이 경우에는 고아 프로세스의 새로운 부모 프로세스로
init
프로세스를 지정함으로써 이 문제를 해결한다. init
프로세스는 주기적으로wait()
시스템 콜을 호출하여 고아 프로세스의 종료 상태를 수집하고 프로세스 식별자와 프로세스 테이블 항목을 반환한다.
실습
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
int main ()
{
pid_t child_pid;
int child_status;
child_pid = fork ();
if (child_pid > 0) {
// parent process will sleep for 30 seconds and exit, without a call to wait()
fprintf(stderr,"parent process - %d\n", getpid());
sleep(30);
exit(0);
}
else if (child_pid == 0) {
// child process will exit immediately
fprintf(stderr,"child process - %d\n", getpid());
exit(0);
}
else if (child_pid == -1) {
// fork() error
perror("fork() call failed");
exit (-1);
}
else {
// this should not happen
fprintf(stderr, "unknown return value of %d from fork() call", child_pid);
exit (-2);
}
return 0;
}
위와 같은 소스 코드를 작성하고 컴파일을 한 뒤에 실행을 해보자.
소스 코드의 대략적인 내용은 부모 프로세스에서 자식 프로세스를 만들고 나서, wait()
호출을 하지 않고 종료 시켜버리는 것이다.
gcc -o zombie zombie.c
실행을 하기 전에, top
명령어를 통해서 좀비 프로세스의 여부를 확인한 모습이다.
좀비 프로세스가 없다는 것을 확인할 수 있다. 아까 작성한 프로그램을 실행 시킨 후에, 다시 한 번더 확인하였을 때는 다음과 같이 표시됨을 확인할 수 있다.
아까는 존재 하지 않았던, 좀비 프로세스가 생긴 것을 확인할 수 있다.