-
Notifications
You must be signed in to change notification settings - Fork 175
Open
Description
有时,我们希望 Go 程序能够智能地处理 Unix 系统信号。例如,我们可能希望服务器在收到 SIGTERM 时做清理操作,处理完已接收的请求后正常关闭,或者让命令行工具在收到 SIGINT 信号时停止处理输入。下面会演示在 Go 程序里通过 channel中处理信号的方法。
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal)
done := make(chan bool)
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")
}Go 信号通知通过在Channel上发送 os.Signal 信号值来工作。通过make(chan os.Signal)创建一个接收系统信号的通道,signal.Notify将创建的通道进行注册,让其能够接收到后面参数指定的类型的系统信号。
下面是一个通过监听SIGTERM信号,优雅关停 gRPC Server的例子:
func main() {
// ...
errChan := make(chan error)
stopChan := make(chan os.Signal)
// bind OS events to the signal channel
signal.Notify(stopChan, syscall.SIGTERM, syscall.SIGINT)
// run blocking call in a separate goroutine, report errors via channel
go func() {
if err := grpcServer.Serve(lis); err != nil {
errChan <- err
}
}()
// terminate your environment gracefully before leaving main function
defer func() {
closeDbConnections()
}()
// block until either OS signal, or server fatal error
select {
case err := <-errChan:
log.Printf("Fatal error: %v\n", err)
case <-stopChan:
server.GracefulStop()
}Metadata
Metadata
Assignees
Labels
No labels