我正在尝试在 Go 中"fork off"后台进程 - 在 Mac 和 Linux 上运行良好,但在 Windows 上关闭终端时会死亡



考虑这个简单的Go程序,它演示了"分叉"的标准方法。Go中的后台进程。当它运行时,它应该立即将自己发送到后台,在那里它将每秒一次向output.txt写入递增的整数。它会一直运行,直到你手动终止它。

这个程序在Mac和Linux上工作得很好,但在Windows上有一个奇怪的行为:它似乎工作了,因为我立即得到一个命令提示符,我的进程确实在后台运行,并将这些整数写入output.txt。但是,当我关闭终端窗口时,后台进程被杀死。

这个问题发生在标准的cmd.exe和使用PowerShell的新花哨的Windows终端上。在Mac和Linux上没有这样的问题,它可以很好地存活终端关闭,ssh退出等。

我尝试使用cmd。SysProcAttr设置系统调用。CREATE_NEW_PROCESS_GROUP,但这没有区别。

我的问题是,当终端关闭时,是什么导致它在Windows上死亡,我如何使它停止?

package main
import (
"fmt"
"os"
"os/exec"
"time"
)
var childEnv = "__IS_CHILD"
func main() {
if os.Getenv(childEnv) == "" {
fork()
os.Exit(0)
}
for i := 0; ; i++ {
fmt.Println(i)
time.Sleep(time.Second)
}
}
func fork() {
outfile, err := os.Create("output.txt")
if err != nil {
panic(err)
}
cmd := exec.Command(os.Args[0])
cmd.Env = append(os.Environ(), fmt.Sprintf("%v=%v", childEnv, 1))
cmd.Stdout = outfile
cmd.Stderr = outfile
if err = cmd.Start(); err != nil {
panic(err)
}
}

我明白了。我只需要添加下面的代码,那么当终端窗口关闭时,分离的进程不会死亡。

cmd.SysProcAttr = &syscall.SysProcAttr{
CreationFlags: windows.CREATE_NEW_PROCESS_GROUP | windows.DETACHED_PROCESS,
}

这里有关于Windows进程创建标志的文档:https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags

相关内容

最新更新