我想捕获从控制台发送的Ctrl+C (SIGINT)信号,并打印一些部分运行总数。


当前回答

您可以使用不同的gor例程来检测系统调用。SIGINT和系统调用。SIGTERM信号,并使用signal.Notify将它们中继到通道。您可以使用通道发送一个钩子到该goroutine,并将其保存在函数片中。当在通道上检测到关闭信号时,您可以在片中执行这些功能。这可用于清理资源、等待运行goroutine完成、持久化数据或打印部分运行总数。

我写了一个小而简单的实用程序来在关机时添加和运行钩子。希望对大家有所帮助。

https://github.com/ankit-arora/go-utils/blob/master/go-shutdown-hook/shutdown-hook.go

你可以用“延迟”的方式来做到这一点。

优雅地关闭服务器:

srv := &http.Server{}

go_shutdown_hook.ADD(func() {
    log.Println("shutting down server")
    srv.Shutdown(nil)
    log.Println("shutting down server-done")
})

l, err := net.Listen("tcp", ":3090")

log.Println(srv.Serve(l))

go_shutdown_hook.Wait()

其他回答

只是为了记录如果有人需要一种方法来处理Windows上的信号。

我有一个要求,从程序a通过os/exec调用程序B,但程序B从未能够优雅地终止,因为通过cmd.Process.Signal(sycall . sigterm)或其他信号发送信号在Windows上不支持。

我通过创建一个临时文件作为信号来处理这个问题。例如,程序A创建文件.signal。术语和程序B需要检查该文件是否以间隔为基础存在。如果文件存在,它将退出程序,并在需要时处理清理。

我相信还有其他方法,但这招管用。

您可以使用不同的gor例程来检测系统调用。SIGINT和系统调用。SIGTERM信号,并使用signal.Notify将它们中继到通道。您可以使用通道发送一个钩子到该goroutine,并将其保存在函数片中。当在通道上检测到关闭信号时,您可以在片中执行这些功能。这可用于清理资源、等待运行goroutine完成、持久化数据或打印部分运行总数。

我写了一个小而简单的实用程序来在关机时添加和运行钩子。希望对大家有所帮助。

https://github.com/ankit-arora/go-utils/blob/master/go-shutdown-hook/shutdown-hook.go

你可以用“延迟”的方式来做到这一点。

优雅地关闭服务器:

srv := &http.Server{}

go_shutdown_hook.ADD(func() {
    log.Println("shutting down server")
    srv.Shutdown(nil)
    log.Println("shutting down server-done")
})

l, err := net.Listen("tcp", ":3090")

log.Println(srv.Serve(l))

go_shutdown_hook.Wait()

你可以使用os/signal包来处理传入信号。Ctrl+C是SIGINT,所以你可以用它来捕获os.Interrupt。

c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func(){
    for sig := range c {
        // sig is a ^C, handle it
    }
}()

终止程序并打印信息的方式完全取决于您。

(在发布的时候)上面接受的答案中有一两个小错字,所以这里是清理后的版本。在这个例子中,当接收到Ctrl+C时,我将停止CPU分析器。

// capture ctrl+c and stop CPU profiler                            
c := make(chan os.Signal, 1)                                       
signal.Notify(c, os.Interrupt)                                     
go func() {                                                        
  for sig := range c {                                             
    log.Printf("captured %v, stopping profiler and exiting..", sig)
    pprof.StopCPUProfile()                                         
    os.Exit(1)                                                     
  }                                                                
}()    

Death是一个简单的库,它使用通道和等待组来等待关闭信号。一旦接收到信号,它就会在所有你想要清除的结构上调用close方法。