2016-03-17 5 views
7

Ich habe eine Anwendung in Go, die die STDIN und STDOUT von Binärdateien umleitet und sie dann ausführt. In aller Kürze tue mir:Golang: Kinderprozesse werden zu Zombies

- 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

ich bemerkte, wenn der Prozess für den Befehl B Ausfahrten während Befehl A ausgeführt wird, es einen Zombie-Prozess in der Prozesstabelle wird.

Hier ist ein Beispiel:

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

cmdAStdin := commandA.StdinPipe() 

commandB.Stdout = cmdAStdin 

commandA.Start() 
commandB.Start() 

Warum commandB ein Zombie werden, wenn es austritt, während Commanda noch läuft? Ich laufe Go 1.5 auf Ubuntu 14.

Antwort

11

Wenn ein Prozess beendet wird, wird IMMER wird zu einem Zombie, unabhängig davon, was andere Prozesse laufen. So funktioniert der Prozessabschluss. Der Prozess bleibt so lange ein Zombie, bis seine Eltern wait aufrufen, um ihren Exit-Status zu erhalten, oder anzeigt, dass sie an Kindern uninteressiert ist, indem sie SIGCHLD ignoriert (was möglicherweise vor dem Beenden des Kindes geschehen ist). Es bleibt solange ein Zombie, bis der Exit-Status verloren geht.

In Ihrem Beispiel scheint es, dass Ihr Prozess (derjenige, der die Prozesse erstellt) der Elternteil ist, also bleiben sowohl A als auch B als Zombies, bis Ihr Prozess sie sammelt.

Wenn ein Prozess beendet wird, während er noch untergeordnete Elemente (entweder ausgeführt oder Zombies) hat, werden diese untergeordneten Elemente zum übergeordneten Prozess des ausgehenden Prozesses umkonfiguriert, der den Beendigungsstatus (Aufräumen der Zombies) ignoriert.

+0

SIGCHLD wird also von den Kind-Prozessen gesendet, bevor sie Zombies werden? Wie kann man SIGCHLD dann "ignorieren"? Indem Sie das Signal fangen und nichts tun? – AJPennster

+0

SIGCHLD wird vom Kernel gesendet, wenn ein Kind ein Zombie macht. Wenn du SIGCHLD ignorieren willst und immer noch Zombies bekommst, setze die SIGCHLD-Aktion auf SIG_DFL (den Standard) und nicht auf SIG_IGN - die Standardaktion ist, nichts zu tun, aber Zombies zu bekommen. –

+0

Ich möchte die Zombies nicht, ich möchte, dass die ausgetretenen Prozesse aufgeräumt werden. Ich habe versucht, Signale in der Hauptanwendung einzurichten, um SIGCHLD zu ignorieren, und das machte immer noch Zombies, so dass ich am Ende Wait() anrufe. – AJPennster

2

Stimmen Sie der ersten Antwort zu, dass das Beenden von Prozessen zu Zombies wird, bis der Prozess von einem anderen Prozess abgewartet wird. So gehe ich mit den Dingen um.

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) 
} 
Verwandte Themen