为了账号安全,请及时绑定邮箱和手机立即绑定

Golang:子进程变成僵尸

Golang:子进程变成僵尸

Go
qq_花开花谢_0 2021-12-20 19:32:40
我在 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我注意到每当命令 A 运行时命令 B 的进程退出,它就会成为进程表中的僵尸进程。下面是一个例子:commandA := exec.Command("samplebin")commandB := exec.Command("sample2bin")cmdAStdin := commandA.StdinPipe()commandB.Stdout = cmdAStdincommandA.Start()commandB.Start()如果 commandB 在 commandA 仍在运行时退出,为什么它会变成僵尸?我在 Ubuntu 14 上运行 Go 1.5。
查看完整描述

2 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

当一个进程退出时,它总是变成僵尸,而不管其他进程正在运行。这就是进程终止的工作方式。该进程将保持僵尸wait状态,直到其父调用获取其退出状态,或者通过忽略 SIGCHLD(可能在子退出之前就已存在)指示它对子进程不感兴趣。在这种情况发生之前,它将保持僵尸状态,以免退出状态丢失。

在您的示例中,您的进程(创建进程的进程)似乎是父进程,因此 A 和 B 都将保持僵尸状态,直到您的进程收集它们。

如果一个进程在它还有子进程(正在运行或僵尸进程)时退出,这些子进程将被重新分配给退出进程的父进程,这通常会忽略退出状态(清除僵尸进程)。


查看完整回答
反对 回复 2021-12-20
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

同意第一个答案,即退出进程变成僵尸,直到该进程被另一个进程等待。这就是我在 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)

}


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 288 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信