我想捕获从控制台发送的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()
其他回答
你可以使用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)
}
}()
上面所有的代码拼接起来都可以工作,但是gobyexample的信号页面有一个非常干净完整的信号捕获示例。值得在这个列表中加上。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
来源:gobyexample.com/signals
您可以使用不同的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()
看看这个例子
当我们运行这个程序时,它会阻塞等待一个信号。通过输入Ctrl+C(终端显示为^C),我们可以发送一个SIGINT信号,导致程序打印中断,然后退出。
信号。Notify注册给定通道以接收指定信号的通知。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sig := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sig
fmt.Println()
fmt.Println(sig)
done <- true
fmt.Println("ctrl+c")
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
检测HTTP请求取消
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/path", func(writer http.ResponseWriter, request *http.Request) {
time.Sleep(time.Second * 5)
select {
case <-time.After(time.Millisecond * 10):
fmt.Println("started")
return
case <-request.Context().Done():
fmt.Println("canceled")
}
})
http.ListenAndServe(":8000", mux)
}