Go 为什么是子流程;睡眠10“;不终止吗?

Go 为什么是子流程;睡眠10“;不终止吗?,go,unix,Go,Unix,我需要测试一个进程是否终止,我所拥有的只是它的pid号。为此,我测试伪文件“/proc/”是否存在 在为这个函数编写测试时,我注意到进程没有按预期终止 对于测试,我将“sleep 10”作为子进程运行,该子进程应运行10秒。启动此过程后,我轮询伪文件“/proc/”是否消失。该伪文件永远不会消失,并且不会检测到子进程的终止 测试golang游乐场的代码会重现以下问题: 我检查了流程是否已创建,pid是否正确。在检查过程时,可以看到它变成了。它并没有因此被移除 问题如下: 为什么子进程不终止 如何

我需要测试一个进程是否终止,我所拥有的只是它的pid号。为此,我测试伪文件“/proc/”是否存在

在为这个函数编写测试时,我注意到进程没有按预期终止

对于测试,我将“sleep 10”作为子进程运行,该子进程应运行10秒。启动此过程后,我轮询伪文件“/proc/”是否消失。该伪文件永远不会消失,并且不会检测到子进程的终止

测试golang游乐场的代码会重现以下问题:

我检查了流程是否已创建,pid是否正确。在检查过程时,可以看到它变成了。它并没有因此被移除

问题如下:

  • 为什么子进程不终止
  • 如何更改代码以使其终止
    在操作系统级别,在任何与POSIX兼容的操作系统(Unix、Linux、Darwin等)中,已完成但尚未被上级收集的进程处于“失效”或“僵尸”状态。它仍然存在,但不能被杀死:它已经死了。它的存在正是为了让它的上级进程能够调用操作系统级别的
    wait
    system调用,从而能够调用操作系统级别的
    wait
    system调用,并看到进程现在已经死了

    一旦它的上级等待它,进程就会被真正删除:不再有一个僵尸进程占用该进程ID。如果您有一个
    /proc
    文件系统,则该进程将从
    /proc
    中消失

    在Go中,调用
    cmd.Wait()
    调用操作系统级别的
    Wait
    调用,这就是实现这一点的方法。如果要收集此
    cmd.Wait()
    的结果,一个好方法是通过通道发送


    (如果你想产生一个长时间运行的进程,而不是等待它,你可以拒绝它,这样你就不再是它的上级了。正确执行此操作的详细信息充满了操作系统特有的窍门,例如丢弃控件TTY、设置会话、使用
    procctl
    prctl
    ,等等。)

    为什么不使用cmd.Wait来等待程序退出?您必须始终对进程调用
    Wait
    。@Volker,因为我只有pid。我没有cmd。这只是一个测试程序。对于pid,我发现测试程序是否终止的唯一等待是检查pid是否存在于“/proc/”中。但是,如果我在
    for
    循环之前添加
    go cmd.wait()
    ,程序的行为与预期一样。子进程未标记为
    已失效
    package main
    
    import (
        "fmt"
        "log"
        "os"
        "os/exec"
        "strconv"
        "time"
    )
    
    func main() {
        fmt.Println("Hello, playground")
    
        cmd := exec.Command("sleep", "10")
        if err := cmd.Start(); err != nil {
            log.Fatal("unexpected error:", err)
        }
        pidStr := strconv.Itoa(cmd.Process.Pid)
        log.Println("sleep pid:", pidStr)
    
        for {
            if _, err := os.Stat("/proc/" + pidStr); os.IsNotExist(err) {
                log.Println("detect termination of /proc/" + pidStr)
                return
            }
            log.Println("pgm /proc/" + pidStr + " is running")
            time.Sleep(3 * time.Second)
        }
    }