检测僵尸子进程
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
}
最好的解决方案(对我来说)是:
- 添加一个信号处理程序监听 SIGCHLD
- 收到 SIGCHLD 后,调用 cmd.Wait()
这样僵尸进程就会消失
我的 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
}
最好的解决方案(对我来说)是:
- 添加一个信号处理程序监听 SIGCHLD
- 收到 SIGCHLD 后,调用 cmd.Wait()
这样僵尸进程就会消失