go 语言 系统信号捕捉
信号类型
不同平台信号定义有所不同,通过命令
man signal
可获取各平台详细的信号介绍。
Go 中的 Signal 发送和处理
- golang中对信号的处理主要使用os/signal包中的两个方法:
- notify方法用来监听收到的信号
- stop方法用来取消监听
监听全部信号
package main
import (
"fmt"
"os"
"os/signal"
)
// 监听全部信号
func main() {
//合建chan
c := make(chan os.Signal)
//监听所有信号
signal.Notify(c)
//阻塞直到有信号传入
fmt.Println("启动")
s := <-c
fmt.Println("退出信号", s)
}
编译 go build example-1.go
启动 ./example-1
ctrl+c退出,输出 退出信号 interrupt
kill pid 输出 退出信号 terminated
监听指定信号
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
// 监听指定信号
func main() {
//合建chan
c := make(chan os.Signal)
//监听指定信号 ctrl+c kill
signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGUSR1, syscall.SIGUSR2)
//阻塞直到有信号传入
fmt.Println("启动")
//阻塞直至有信号传入
s := <-c
fmt.Println("退出信号", s)
}
编译 go build example-2.go
启动 ./example-2
ctrl+c退出,输出 退出信号 interrupt
kill pid 输出 退出信号 terminated
kill -USR1 pid 输出 退出信号 user defined signal 1
kill -USR2 pid 输出 退出信号 user defined signal 2
优雅退出 go 守护进程
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
// 优雅退出go守护进程
func main() {
//创建监听退出chan
c := make(chan os.Signal)
//监听指定信号 ctrl+c kill
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2)
go func() {
for s := range c {
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
fmt.Println("退出", s)
ExitFunc()
case syscall.SIGUSR1:
fmt.Println("usr1", s)
case syscall.SIGUSR2:
fmt.Println("usr2", s)
default:
fmt.Println("other", s)
}
}
}()
fmt.Println("进程启动...")
sum := 0
for {
sum++
fmt.Println("sum:", sum)
time.Sleep(time.Second)
}
}
func ExitFunc() {
fmt.Println("开始退出...")
fmt.Println("执行清理...")
fmt.Println("结束退出...")
os.Exit(0)
}
kill -USR1 pid 输出 usr1 user defined signal 1
kill -USR2 pid usr2 user defined signal 2
kill pid 退出 terminated 开始退出… 执行清理… 结束退出…
执行输出 go build example-3.go ./example-3
进程启动… sum: 1 sum: 2 sum: 3 sum: 4 sum: 5 sum: 6 sum: 7 sum: 8 sum: 9 usr1 user defined signal 1 sum: 10 sum: 11 sum: 12 sum: 13 sum: 14 usr2 user defined signal 2 sum: 15 sum: 16 sum: 17 退出 terminated 开始退出… 执行清理… 结束退出…