Golang:子进程变成僵尸
Golang: Child Processes become Zombies
我在 Go 中有一个应用程序,它重新路由二进制文件的 STDIN 和 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
我注意到每当命令 B 的进程退出而命令 A 是 运行 时,它就会成为进程 table 中的僵尸进程。
这是一个例子:
commandA := exec.Command("samplebin")
commandB := exec.Command("sample2bin")
cmdAStdin := commandA.StdinPipe()
commandB.Stdout = cmdAStdin
commandA.Start()
commandB.Start()
为什么commandB在commandA还在运行的时候退出了就变成了Zombie?我是 运行 Ubuntu 14.
Go 1.5
当一个进程退出时,它总是变成僵尸,不管其他进程是什么运行。这就是进程终止的工作方式。该进程将保持僵尸状态,直到其父进程调用 wait
获取其退出状态,或通过忽略 SIGCHLD(可能在子进程退出之前)表明它对子进程不感兴趣。在这种情况发生之前,它将保持僵尸状态,以免退出状态丢失。
在您的示例中,您的进程(创建进程的进程)似乎是父进程,因此 A 和 B 都将保持僵尸状态,直到您的进程收集它们。
如果一个进程在它还有子进程(运行 或僵尸进程)时退出,这些子进程将被重新设置为退出进程的父进程,通常会忽略退出状态(清除僵尸进程)。
同意第一个答案,即退出的进程会变成僵尸,直到该进程被另一个进程等待。这是我在 go 中处理事情的方式。
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)
}
我在 Go 中有一个应用程序,它重新路由二进制文件的 STDIN 和 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
我注意到每当命令 B 的进程退出而命令 A 是 运行 时,它就会成为进程 table 中的僵尸进程。
这是一个例子:
commandA := exec.Command("samplebin")
commandB := exec.Command("sample2bin")
cmdAStdin := commandA.StdinPipe()
commandB.Stdout = cmdAStdin
commandA.Start()
commandB.Start()
为什么commandB在commandA还在运行的时候退出了就变成了Zombie?我是 运行 Ubuntu 14.
Go 1.5当一个进程退出时,它总是变成僵尸,不管其他进程是什么运行。这就是进程终止的工作方式。该进程将保持僵尸状态,直到其父进程调用 wait
获取其退出状态,或通过忽略 SIGCHLD(可能在子进程退出之前)表明它对子进程不感兴趣。在这种情况发生之前,它将保持僵尸状态,以免退出状态丢失。
在您的示例中,您的进程(创建进程的进程)似乎是父进程,因此 A 和 B 都将保持僵尸状态,直到您的进程收集它们。
如果一个进程在它还有子进程(运行 或僵尸进程)时退出,这些子进程将被重新设置为退出进程的父进程,通常会忽略退出状态(清除僵尸进程)。
同意第一个答案,即退出的进程会变成僵尸,直到该进程被另一个进程等待。这是我在 go 中处理事情的方式。
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)
}