2013-04-18 31 views
10

Vikipedi diyor ki: "Sona eren ama asla ebeveyn tarafından beklemeyen bir çocuk süreci bir zombi süreci haline gelir." Ben bu programı çalıştırın: Bu bir zombi sürecini oluştururNeden zombi işlemleri var?

#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); 
     } 
    } 
} 

ama bir zombi süreci burada oluşturulur neden anlamıyor?

programın çıktısı

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 
.... 
..... 

olduğunu Ama neden "çocuk süreç sona erer ancak ebeveyn tarafından bekledi değil" bu durumda bu?

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

Neden: Kodunuzda

+0

Soruyor musun? Öyle görünüyor ki, gördüğüm sorunun tek cevabı "çünkü zombi süreçleri böyle tanımlanıyor". –

+0

** "zombi işleminin neden burada yaratıldığını anlayamadım" ** Bunun nedeni, çocuğun çıkış durumunu okumak için wait() 'yi çağırmamanız ve dolayısıyla işlem tablosunda girişinin kalmasıdır. . –

+0

Thats tamam. Ama çocuk bir süre için çalışır ve orada herhangi bir zombi yok – user567879

cevap

25

, zombi exit(0) (aşağıda okla comment) oluşturulur? Çünkü üzerinde hiç wait edemezsiniz. Bir şey waitpid(pid)'u aradığında, çıkış kodu gibi işlemle ilgili postmortem bilgileri döndürür. Ne yazık ki, işlemden çıkıldığında, çekirdek bu işlem girişini elden çıkaramaz veya dönüş kodu kaybolacaktır. Bu nedenle, birisi için wait için bekler ve işlem tablosuna giriş dışında herhangi bir belleğe sahip olmasa bile bu işlem girişini bırakır. Bu tam olarak zombi olarak adlandırılır.

  1. üst süreçte yerde waitpid() ekleyin:

    Sen zombileri oluşturmaktan kaçınmak için birkaç seçenek vardır. Örneğin, bunu yaparken yardımcı olacaktır:

    pid=fork(); if (pid==0) { exit(0); } else { waitpid(pid); // <--- this call reaps zombie // some parent code ... } 
  2. torun hala hayatta ikenfork() çift çocukta torun ve çıkış elde etmek gerçekleştirin. Ebeveynler (çocuklarımız) ölürse, torunlar init tarafından otomatik olarak kabul edilecek, bu demektir ki torun ölürse, init tarafından otomatik olarak wait düzenlenir. Başka bir deyişle, böyle bir şey yapmak gerekir:

    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. Açıkça ebeveyn yılında SIGCHLD sinyalini görmezden. Çocuk ölürken, ebeveyn çocuk ölümüne tepki göstermesine izin veren SIGCHLD sinyalini gönderir. Bu sinyali aldıktan sonra waitpid() numaralı telefonu arayabilir veya açık göz ardı etme sinyali işleyicisini (signal() veya sigaction() kullanarak) kurabilirsiniz; bu, çocuğun zombilere dönüşmemesini sağlar. Başka bir deyişle, böyle bir şey: Bir zombi sürecinin kavramı Unix tanıtıldı neden

    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 sinyali göz ardı neden zombi öldürüyor? Çocuk sürecinin bir zombi olmadığından emin olmasını anlıyorum. Yani program bitince, zombi olmayan süreç kapanacak mı? Ve bir program çıktıktan sonra zombi süreci çıkmayacak mı? – user234159

+3

Yine, zombi öldürülemez: Zaten ölmüş, kalan her şey çekirdek işlem tablosuna girdi. SIGCHLD'i göz ardı etmek, çekirdeği hemen bu girişi elden geçirmenin tamam olduğunu bilmesini sağlar. – mvp