2013-04-18 23 views
10

विकिपीडिया कहता है "एक बच्चा प्रक्रिया जो समाप्त हो जाती है लेकिन इसके माता-पिता द्वारा कभी भी इंतजार नहीं किया जाता है, वह ज़ोंबी प्रक्रिया बन जाता है।" मैं इस कार्यक्रम को चलाता हूं:ज़ोंबी प्रक्रिया क्यों मौजूद है?

#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

** "यह समझ में नहीं आया कि ज़ोंबी प्रक्रिया क्यों बनाई गई है" ** ऐसा इसलिए होगा क्योंकि आप बच्चे की निकास स्थिति को पढ़ने के लिए 'प्रतीक्षा()' नहीं बुला रहे हैं, और इसलिए इसकी प्रविष्टि प्रक्रिया तालिका में पीछे छोड़ दी गई है । –

+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 द्वारा अपनाए जाएंगे यदि उनके माता-पिता (हमारे बच्चे) की मृत्यु हो जाती है, जिसका अर्थ है कि अगर दादा मर जाता है, तो यह स्वचालित रूप से wait एड init पर होगा। दूसरे शब्दों में, आप कुछ इस तरह करने की जरूरत है:

    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

संबंधित मुद्दे