除了SIGKILL信号外,在Windows上无法终止进程的信号。

huangapple go评论159阅读模式
英文:

Signal other than SIGKILL not terminating process on Windows

问题

我正在通过Go启动一个简单的Java应用程序,目标是证明Go可以发送类似于SIGQUIT或SIGTERM的信号,而Java可以捕获并适当处理它(即优雅地关闭)。当我在命令行上运行Java程序并发送CTRL+C时,Java程序正确地捕获了信号。

然而,当我通过Go启动Java程序并尝试发送信号时,Java进程既没有终止也没有处理信号。唯一有效的信号是SIGKILL,当然它不会被捕获,只是终止进程。

以下是我Go代码的相关部分:

启动:

startChan := make(chan bool)
go func(startChan chan<- bool) {
	a.Cmd = exec.Command("java", "-jar", "C:\\Code\\sigterm\\TestApp.jar")
	a.Cmd.Stdout = os.Stdout
	a.Cmd.Stderr = os.Stderr

	launchErr := a.Cmd.Start()
	if launchErr != nil {
		fmt.Println("无法启动应用程序:" + launchErr.Error())
	}
	startChan <- true
}(startChan)

停止:

func (a *App) Stop(timeout time.Duration) {
  a.Cmd.Process.Signal(syscall.SIGQUIT) //不起作用
  a.Cmd.Process.Signal(syscall.SIGTERM) //不起作用
  a.Cmd.Process.Signal(syscall.SIGKILL) //起作用
}

顺便说一下,这是在Windows上。我尝试通过启动另一个程序(记事本)进行测试,结果也是一样的;也就是说,只有SIGKILL起作用。我已经确认Go获取了正确的PID等信息,所以信号应该发送到了正确的位置。

有关如何使其工作的任何想法吗?

英文:

I am launching a simple Java application through Go, with the goal of proving that Go can send a signal like SIGQUIT or SIGTERM, and the Java can catch that and handle it appropriately (i.e. shutdown gracefully). When I run the Java program on the command line and send it a CTRL+C, the Java program correctly catches the signal.

However, when I launch the Java program through Go and attempt to send the process a signal, the Java process is neither terminated nor does it handle the signal. The only one that works is SIGKILL, which of course is not caught, and simply kills the process.

Here are the relevant parts of my Go code:

Start:

startChan := make(chan bool)
go func(startChan chan<- bool) {
	a.Cmd = exec.Command("java", "-jar", "C:\\Code\\sigterm\\TestApp.jar")
	a.Cmd.Stdout = os.Stdout
	a.Cmd.Stderr = os.Stderr

	launchErr := a.Cmd.Start()
	if launchErr != nil {
		fmt.Println("Unable to start app:" + launchErr.Error())
	}
	startChan <- true
}(startChan)

Stop:

func (a *App) Stop(timeout time.Duration) {
  a.Cmd.Process.Signal(syscall.SIGQUIT) //Does not work
  a.Cmd.Process.Signal(syscall.SIGTERM) //Does not work
  a.Cmd.Process.Signal(syscall.SIGKILL) //Works
}

This is on Windows, by the way. I tried it by launching another program (notepad) and got the same results; that is, only SIGKILL worked. I have confirmed that Go is getting the correct PID and so forth, so the signal should be going to the right place.

Any ideas about how I can get this to work?

答案1

得分: 5

根据文档,似乎不支持此操作:

https://godoc.org/os#Process.Signal

> 在Windows上发送中断信号尚未实现。

此外,可以查看此问题讨论以获取更多关于为什么无法实现的上下文信息:

https://github.com/golang/go/issues/6720

英文:

This does not seem to be supported as stated in the documentation:

https://godoc.org/os#Process.Signal

> Sending Interrupt on Windows is not implemented.

Also, see this issue discussion to get more context on why it could not be done:

https://github.com/golang/go/issues/6720

答案2

得分: 2

syscall包是根据操作系统进行定制的(https://golang.org/pkg/syscall/#pkg-overview)。
尽管在Windows上没有实现中断,但信号仍然可用。

在信号包本身中有一个Windows的示例1
可以在这里找到一个交互式版本(go run2

英文:

syscall package is tailored to the OS (https://golang.org/pkg/syscall/#pkg-overview).
Although interrupt is not implemented on Windows, signaling is usable.

There is an example in the signal package itself for Windows.
An interactive version (go run) is available here.

huangapple
  • 本文由 发表于 2017年7月26日 01:26:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/45309984.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定