os/signal golang的信号监听
func Notify(c chan<- os.Signal, sig ...os.Signal)函数用于当操作系统向当前进程发送信号时发出通知
通过管道C来接受信号,信号类型只能为os.Signal ,
后面的变长参数代表可以处理任意多个信号类型。
使用方式如下:
c := make(chan os.Signal,1)
sigs := []os.Signal{syscall.SIGINT,syscall.SIGQUIT}
signal.Notify(c,sigs...)
向指定进程发送信号:
首先我们必须获取进程的pid,一般是通过shell命令
通过process,_ := os.FindProcess(pid) 获得进程值
使用proc.Signal(syscall.XXX) 来实现向指定进程发送信号
上面那些都不常用,我唯一用到的就是最近研究热重启看到的
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM, syscall.SIGUSR2)
for {
sig := <-ch
log.Printf("signal: %v", sig)
// timeout context for shutdown
ctx, _ := context.WithTimeout(context.Background(), 20*time.Second)
switch sig {
case syscall.SIGINT, syscall.SIGTERM:
// stop
log.Printf("stop")
signal.Stop(ch)
server.Shutdown(ctx)
log.Printf("graceful shutdown")
return
case syscall.SIGUSR2:
// reload
log.Printf("reload")
err := reload()
if err != nil {
log.Fatalf("graceful restart error: %v", err)
}
server.Shutdown(ctx)
log.Printf("graceful reload")
return
}
可以看到上面代码通过 Notify 的参数一 也就是管道c 拿到信号 使用switch 做判断,其中SIGUSR2 是自定义信号
上面注意在关闭信号通道时 使用
signal.Stop(c) 来声明恢复系统对你监听信号的默认操作
建议加上 close(c) 再回收一下 通道。不然c 会阻塞住。
浙公网安备 33010602011771号