본문 바로가기
IT/OS

[OS] 좀비 프로세스(Zombie Process)란? 부모프로세스와 자식프로세스

by 퐁시냥 2022. 1. 15.

아마 한 번쯤은 좀비 프로세스(Zombie Process)에 대해서 들어봤을 것이다.

좀비 프로세스의 의미와 예제, 부모 프로세스와 자식 프로세스에 대해 알아보자.

 

프로세스 실행 과정

  • exe 실행
  • 코드 영역 / 데이터 영역 메모리 로드
  • 힙 / 스택 영역 생성
  • PCB 초기화

→ 처음 0번 프로세스가 실행될 때 처음 만들어지는 것

이후 실행되는 다른 프로세스는 0번에서 복사 : fork()

→ 이렇게 복사하는 이유는 새로 생성하는 것보다 복사하는 게 더 빠르기 때문

자식 프로세스와 부모 프로세스

자식 프로세스(child process)는 부모 프로세스(parent process)의 내용을 그대로 복사

  • 코드 / 데이터 영역 메모리 로드
  • 힙 / 스택 영역 생성
  • PCB 초기화

부모 프로세스와 자식 프로세스

자식프로세스는 자기가 원하는 코드는 어떻게 실행할까? : exec() 사용

  • 코드 영역데이터 영역을 원하는 값으로 덮어씀
  • wait() → 자식 프로세스를 기다림. 리턴 받고 자식 프로세스 종료.
  • exit() → 자식 프로세스가 부모 프로세스에게 정상 종료를 알리는 것.

좀비 프로세스(Zombie Process)

  • 프로세스가 종료 될 때, 마지막 문장의 실행을 끝내고, exit() 시스템 호출을 사용하여 운영체제에게 자신의 삭제를 요청하면서 종료된다.
  • 이 시점에서, 프로세스는 자신의 부모가 호출한 wait() 시스템 호출을 통해서, 상태 값을 반환할 수 있고, 물리 메모리와 가상 메모리, 열린 파일, 입출력 버퍼를 포함한 프로세스의 모든 자원이 운영체제로 반납된다.
  • 부모 프로세는 wait() 시스템 호출을 사용하여 자식 프로세스가 종료할 때를 기다릴 수 있고, 부모가 자식의 종료 상태를 얻어 낼 수 있도록 하나의 인자를 전달 받는다. 이 시스템 호출은 부모가 어떤 자식이 종료되었는지 구별할 수 있도록 종료된 자식의 프로세스 식별자를 반환한다.
  • 프로세스가 종료되면 사용하던 자원은 운영체제가 되찾아가게 된다. 그러나 프로세스의 종료 상태가 저장되는 프로세스 테이블의 해당 항목은 부모 프로세스가 wait()을 호출할 때까지 남아있게 된다.
  • 따라서 종료가 되었지만 부모 프로세스가 아직 wait() 호출을 하지 않은 프로세스좀비(zombie) 프로세스라고 한다.
  • 모든 프로세스는 종료하게 되면, 좀비 상태가 되지만 아주 짧은 시간 동안 머무르게 되고, 부모가 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;
}

컴파일(gcc)

gcc -o zombie zombie.c

실행

./zombie

좀비프로세스 실행 확인

1. 프로세스 실행 결과

부모 PID : 34792, pid : 34793
자식 시작 PID : 34793
자식 종료
부모 종료

2. 좀비 프로세스 확인(STAT : Z+) 

ps aux | grep 'Z'
USER               PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
_nsurlsessiond   34351   0.0  0.0 408491760   3648   ??  Ss    5:32PM   0:00.16 /System/Library/PrivateFrameworks/StreamingZip.framework/Versions/A/XPCServices/com.apple.StreamingUnzipService.xpc/Contents/MacOS/com.apple.StreamingUnzipService
pongdu           34835   0.0  0.0 408112528   1408 s000  S+    5:51PM   0:00.00 grep Z
pongdu           34819   0.0  0.0        0      0 s001  Z+    5:51PM   0:00.00 (zombie)

출처

댓글