在Windows和Linux中使用Golang捕获Ctrl+C或任何其他进程终止信号的方法

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

Capturing ctrl+c or any other process terminating signals in windows and linux with golang

问题

我正在尝试使用Go构建一个聊天室应用程序,并且我希望在客户端使用Ctrl+C或按下终端的关闭按钮时调用注销函数。

我尝试了这里这里给出的方法,但它们没有捕获到任何信号(在Windows 10和Fedora 23上尝试过)。这是我的代码片段:

sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
    syscall.SIGHUP,
    syscall.SIGINT,
    syscall.SIGTERM,
    syscall.SIGQUIT)
go func() {
    _ = <-sigc
    fmt.Println("ctrl+c pressed")
    client.Logout()
}()

我还有一些其他函数在使用goroutine并发运行,这是导致该函数无法捕获任何信号的原因吗?

任何帮助将不胜感激。

英文:

I am trying to build a chatroom application in go and I want to call logout function when client uses ctrl+c or presses close buttom of the terminal. <br/>
I tried methods given here and here but they were not capturing any signals(tried in Windows 10 and Fedora 23). Here is my code snippet,

sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
	syscall.SIGHUP,
	syscall.SIGINT,
	syscall.SIGTERM,
	syscall.SIGQUIT)
go func() {
	_ = &lt;-sigc
	fmt.Println(&quot;ctrl+c pressed&quot;)
	client.Logout()
}()

I have some other functions running concurrently using goroutine, is it the reason behind this function not capturing any signals?

Any help would be appreciated.

答案1

得分: 7

根据os.Signal文档的说明,应该可以在Windows上捕获中断信号:https://golang.org/pkg/os/signal/#hdr-Windows。不过我个人没有测试过。

我怀疑你的问题是你应该只使用从os导入的信号,比如os.Interrupt,而不是syscall

根据https://golang.org/pkg/os/#Signal的说明:

在所有系统上都保证存在的信号值只有Interrupt(发送中断信号给进程)和Kill(强制进程退出)。

而根据https://golang.org/pkg/syscall/#pkg-overview的说明:

syscall的主要用途是在其他提供更便携的系统接口的包中使用,比如"os"、"time"和"net"。如果可以的话,请使用这些包而不是syscall。

因此,将你的signal.Notify调用更改为仅捕获os.Interrupt信号。

英文:

According to the docs on os.Signal, it should be possible to catch interrupts on Windows: https://golang.org/pkg/os/signal/#hdr-Windows. I haven't tested this personally, though.

I suspect your problem is that you should only use signals imported from os, such as os.Interrupt, instead of syscall.

From https://golang.org/pkg/os/#Signal:
> The only signal values guaranteed to be present on all systems are Interrupt (send the process an interrupt) and Kill (force the process to exit).

And from https://golang.org/pkg/syscall/#pkg-overview:
> The primary use of syscall is inside other packages that provide a more portable interface to the system, such as "os", "time" and "net". Use those packages rather than this one if you can.

So, change your signal.Notify call to catch only the os.Interrupt signal.

huangapple
  • 本文由 发表于 2016年2月28日 10:22:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/35677972.html
匿名

发表评论

匿名网友

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

确定