检测僵尸子进程

Detect zombie child process

我的 golang 程序启动了一个服务程序,它应该永远 运行,像这样:

cmd := exec.Command("/path/to/service")
cmd.Start()

我不想等待 "service" 的终止,因为它应该永远 运行ning。但是,如果服务以某些错误启动(例如,如果另一个实例已经 运行ning 它将终止),子进程将退出并成为僵尸。

我的问题是,在 cmd.Start() 之后,我能否以某种方式检测子进程是否仍在 运行ning 而不是变成僵尸进程?首选方式可能是:

if cmd.Process.IsZombie() {
    ... ...
}

或者,

procStat := cmd.GetProcessStatus()
if procStat.Zombie == true {
    ... ...
}

即我希望有一些方法可以在不等待其退出代码的情况下获取(子)进程的状态,或者 "peek" 它的状态代码而不阻塞。

谢谢!

根据文档判断,获取进程状态的唯一方法是调用 os.Process.Wait。所以看起来你必须在一个 goroutine 中调用 wait,然后你可以很容易地检查那个 goroutine 是否已经退出:

var cmd exec.Cmd

done := make(chan error, 1)
go func() {
    done <- cmd.Wait()
}()

select {
case err := <-done:
    // inspect err to check if service exited normally
default:
    // not done yet
}

最好的解决方案(对我来说)是:

  1. 添加一个信号处理程序监听 SIGCHLD
  2. 收到 SIGCHLD 后,调用 cmd.Wait()

这样僵尸进程就会消失