2013-04-18 1 views
10

Wikipedia는 "종료되지만 부모가 기다리지 않는 하위 프로세스는 좀비 프로세스가됩니다."라고 말합니다. 이 프로그램을 실행합니다 :왜 좀비 프로세스가 존재합니까?

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
int main() 
{ 
    pid_t pid, ppid; 
    printf("Hello World1\n"); 
    pid=fork(); 
    if(pid==0) 
    { 
     exit(0);  
    } 
    else 
    { 
     while(1) 
     { 
     printf("I am the parent\n"); 
     printf("The PID of parent is %d\n",getpid()); 
     printf("The PID of parent of parent is %d\n",getppid());   
     sleep(2); 
     } 
    } 
} 

이렇게하면 좀비 프로세스가 생성되지만 좀비 프로세스가 여기에 생성 된 이유를 이해할 수 없습니까?

프로그램의 출력은

Hello World1 
I am the parent 
The PID of parent is 3267 
The PID of parent of parent is 2456 
I am the parent 
The PID of parent is 3267 
The PID of parent of parent is 2456 
I am the parent 
.... 
..... 

이다 그러나 이유는 "자식 프로세스가 종료하지만 부모에 의해 기다렸다되지"이 경우이다?

pid=fork(); 
if (pid==0) { 
    exit(0); // <--- zombie is created on here 
} else { 
    // some parent code ... 
} 

이유 : 당신의 코드에서

+0

당신이 묻는? 그것이 의미하는 바에 따르면, 내가보기에 당신의 질문에 대한 유일한 대답은 "좀비 프로세스가 정의 된 것이기 때문에"입니다. –

+0

** "왜 좀비 프로세스가 여기에 만들어 졌는지 이해할 수 없습니다"** 자식의 종료 상태를 읽기 위해'wait() '를 호출하지 않았기 때문에 그 결과가 프로세스 테이블에 남아 있습니다 . –

+0

그게 전부입니다. 그러나 아이가 얼마 동안 뛰고 어떤 좀비도 존재하지 않으면 – user567879

답변

25

은 좀비는 exit(0) (아래 화살표 코멘트)을 작성? 너 결코 wait에 에드 때문에. 무언가가 waitpid(pid)을 호출하면 프로세스에 대한 사후 정보 (예 : 종료 코드)가 반환됩니다. 불행하게도, 프로세스가 종료되면, 커널은이 프로세스 엔트리를 처분 할 수 없으며, 리턴 코드는 잃어 버리게된다. 따라서 어떤 사람은 누군가 wait을 기다리고 프로세스 테이블의 항목을 제외하고는 실제로 메모리를 차지하지 않아도이 프로세스 엔트리를 남겨 둡니다. 정확히 좀비이라고합니다.

  1. 부모 프로세스 어딘가에 waitpid()을 추가

    당신은 좀비를 만드는 피하기 위해 몇 가지 옵션이 있습니다. 예를 들어,이 일을하는 데 도움이됩니다

    pid=fork(); if (pid==0) { exit(0); } else { waitpid(pid); // <--- this call reaps zombie // some parent code ... } 
  2. 는 손자가 살아있는 동안fork() 두 아이의 손자 종료를 얻기 위해 수행합니다. 자녀 (부모)가 사망하면 손자는 init으로 자동 채택됩니다. 즉, 손자가 사망하면 waitinit이 자동으로 적용됩니다. 즉, 같은 것을 할 필요가 :

    pid=fork(); 
    if (pid==0) { 
        // child 
        if (fork()==0) { 
         // grandchild 
         sleep(1); // sleep a bit to let child die first 
         exit(0); // grandchild exits, no zombie (adopted by init) 
        } 
        exit(0);  // child dies first 
    } else { 
        waitpid(pid); // still need to wait on child to avoid it zombified 
        // some parent code ... 
    } 
    
  3. 가 명시 적으로 부모에 SIGCHLD 신호를 무시합니다. 아이가 죽으면, 부모는 아이들의 죽음에 반응하게하는 SIGCHLD 신호를 보낸다. 이 신호를 받으면 waitpid()으로 전화하거나 명시 적 무시 신호 처리기 (signal() 또는 sigaction() 사용)를 설치하면 어린이가 좀비가되지 않도록 할 수 있습니다. 즉,이 같은에서 : 좀비 프로세스의 개념은 유닉스에서 도입 한 이유

    signal(SIGCHLD, SIG_IGN); // <-- ignore child fate, don't let it become zombie 
    pid=fork(); 
    if (pid==0) { 
        exit(0); // <--- zombie should NOT be created here 
    } else { 
        // some parent code ... 
    } 
    
+2

SIGCHLD 신호를 무시하면 좀비가 죽는 이유는 무엇입니까? 나는 그것이 자식 프로세스가 좀비가되지 않도록 확실히한다. 프로그램이 종료되면 비 좀비 프로세스가 종료됩니다. 프로그램이 종료되면 좀비 프로세스가 종료되지 않습니까? – user234159

+3

다시 말하지만, 좀비는 죽을 수 없습니다. 이미 죽었습니다. 남아있는 것은 모두 커널 프로세스 테이블에있는 항목입니다. SIGCHLD를 무시하면 커널이 해당 항목을 즉시 처분해도 상관 없음을 알 수 있습니다. – mvp

관련 문제