2016-03-17 17 views
7

मेरे पास गो में एक एप्लिकेशन है जो एसटीडीआईएन और बाइनरी के STDOUT को दोहराता है और फिर उन्हें चलाता है। संक्षेप में मैं कर रहा हूँ:गोलांग: बाल प्रक्रियाएं लाश बन जाती हैं

- create command object with the binary path (lets call the object command A) - create command object with the binary path (calling it command B) - set the stdout of command B to the stdin of Command A - start command A - start command B

मैंने देखा जब भी आदेश बी बाहर निकलता है के लिए प्रक्रिया है, जबकि आदेश एक चल रहा है, यह प्रक्रिया तालिका में एक ज़ोंबी प्रक्रिया हो जाता है।

commandA := exec.Command("samplebin") 
commandB := exec.Command("sample2bin") 

cmdAStdin := commandA.StdinPipe() 

commandB.Stdout = cmdAStdin 

commandA.Start() 
commandB.Start() 

commandB एक ज़ोंबी बन क्यों अगर यह बाहर निकल जाता है, जबकि Commanda अभी भी चल रहा है:

यहाँ एक उदाहरण है? मैं उबंटू 14 पर गो 1.5 चला रहा हूं।

उत्तर

11

जब कोई प्रक्रिया निकलती है, तो ALWAYS एक ज़ोंबी बन जाती है, भले ही अन्य प्रक्रियाएं चल रही हों। प्रक्रिया प्रक्रिया समाप्त करने का यही तरीका है। प्रक्रिया तब तक एक ज़ोंबी रहेगी जब तक कि इसके माता-पिता wait को बाहर निकलने की स्थिति प्राप्त करने के लिए कॉल न करें, या इंगित करता है कि यह सिगचल (जो बच्चे से बाहर निकलने से पहले हो सकता है) को अनदेखा करके बच्चों में रुचि नहीं है। यह तब तक एक ज़ोंबी रहेगा जब तक ऐसा नहीं होता है, ताकि बाहर निकलने की स्थिति खो जाए।

अपने उदाहरण में, यह प्रतीत होता है कि आपके प्रक्रिया (एक प्रक्रियाओं बनाने) माता-पिता है, इसलिए दोनों ए और बी जब तक अपनी प्रक्रिया उन्हें एकत्र करता लाश के रूप में रहेगा।

यदि कोई प्रक्रिया तब भी निकलती है जब उसके पास अभी भी बच्चे हैं (या तो दौड़ रहे हैं या लाश) हैं, तो उन बच्चों को बाहर निकलने वाली प्रक्रिया के माता-पिता के लिए पुनर्विचार किया जाएगा, जो आम तौर पर बाहर निकलने की स्थिति (ज़ोंबी को साफ़ करने) को अनदेखा कर देगा।

+0

तो, सिग्चेड को लाश बनने से ठीक पहले बच्चों की प्रक्रियाओं द्वारा भेजा जाता है? फिर सिग्चाल्ड को "अनदेखा" कैसे करता है? सिग्नल पकड़कर और कुछ नहीं कर कर? – AJPennster

+0

SIGCHLD कर्नेल द्वारा भेजा जाता है जब एक बच्चा इसे ज़ोंबी बनाने के हिस्से के रूप में करता है। यदि आप इसके बजाय SIG_IGN से SIGCHLD अनदेखी करने के लिए और अभी भी लाश मिलता है, SIG_DFL (डिफ़ॉल्ट) को SIGCHLD कार्रवाई सेट चाहते हैं - डिफ़ॉल्ट कार्रवाई कुछ भी नहीं करना है, लेकिन अभी भी लाश मिलता है। –

+0

मुझे लाश नहीं चाहिए, मैं बाहरी प्रक्रियाओं को साफ करना चाहता हूं। मैंने SIGCHLD को अनदेखा करने के लिए मुख्य एप्लिकेशन में सिग्नल सेट अप करने का प्रयास किया और अभी भी ज़ोंबी बनाये ताकि मैं प्रतीक्षा() को कॉल कर सकूं। – AJPennster

2

प्रक्रियाओं से बाहर निकलने वाले पहले जवाब के साथ सहमति दें जब तक कि प्रक्रिया किसी अन्य प्रक्रिया के लिए प्रतीक्षा न हो जाए। यहां बताया गया है कि मैं चीजों को कैसे संभालता हूं।

package main 

import (
    "bytes" 
    "io" 
    "os" 
    "os/exec" 
) 

func main() { 
    c1 := exec.Command("samplebin") 
    c2 := exec.Command("sample2bin") 

    r, w := io.Pipe() 
    c1.Stdout = w 
    c2.Stdin = r 

    var b2 bytes.Buffer 
    c2.Stdout = &b2 

    // Writing without a reader will deadlock so write in a goroutine 
    go func() { 
     // Close the writer or the pipe will not be closed for c2 
     defer w.Close() 
     defer c1.Wait() 
     c1.Start() 
    }() 
    defer c2.Wait() 
    c2.Start() 
    io.Copy(os.Stdout, &b2) 
} 
संबंधित मुद्दे