在 Go 中终止子进程:解决超时问题
在提供的 Go 代码片段中,尽管设置了 2 秒的超时并尝试使用信号终止子进程,该进程将持续存在并且“完成等待”仍然不打印。此行为表明该进程在超出指定时间后仍保持活动状态。
此问题的根源在于使用 cmd.Process.Signal() 来终止子进程。需要注意的是,该函数仅向主进程发送信号,而不向其子进程发送信号。为了有效终止子进程,需要定位包含子进程的进程组,这可以使用以下方法来完成:
// First, create the command and set up its attributes cmd := exec.Command( some_command ) cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} // Then, start the command cmd.Start() // Next, obtain the process group ID of the child process pgid, err := syscall.Getpgid(cmd.Process.Pid) if err == nil { // If the process group ID is successfully obtained, terminate it syscall.Kill(-pgid, 15) // note the minus sign } // Finally, wait for the command to complete cmd.Wait()
通过在 syscall.SysProcAttr 中将 Setpgid 设置为 true,我们指示操作系统为子进程创建一个新的进程组,确保发送到父进程的信号不会影响子进程。 -pgid 中的减号确保信号发送到进程组的所有成员,包括任何子进程。
此解决方案是特定于平台的,可能不适用于所有操作系统。然而,据报道它可以在 OSX Yosemite 和各种 Linux 发行版上运行,而其在 Windows 和 BSD 上的兼容性仍不确定。
以上是Go 发生超时时如何可靠地终止子进程?的详细内容。更多信息请关注PHP中文网其他相关文章!