golang优雅关机

63 阅读1分钟

func main() {
	sig()
}

//每一个监听系统信号的g都能收到
func sig() {
	wg := sync.WaitGroup{}
	fmt.Println("start")
	go func() {
		wg.Add(1)
		defer wg.Done()
		quit := make(chan os.Signal, 1) // 创建一个接收信号的通道
		// kill 默认会发送 syscall.SIGTERM 信号
		// kill -2 发送 syscall.SIGINT 信号,我们常用的Ctrl+C就是触发系统SIGINT信号
		// kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它
		// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit
		signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
		<-quit                                               // 阻塞在此,当接收到上述两种信号时才会往下执行
		log.Println("Shutdown Server ...1")
	}()
	go func() {
		wg.Add(1)
		defer wg.Done()
		quit := make(chan os.Signal, 1) // 创建一个接收信号的通道
		signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
		<-quit                                               // 阻塞在此,当接收到上述两种信号时才会往下执行
		log.Println("Shutdown Server ...2")
		time.Sleep(10 * time.Second)
	}()
	time.Sleep(1 * time.Second)//防止子g还没add直接运行完了
	wg.Wait()
}

ctrl+c以后要等10秒才会退出

运行结果:
start
^C2022/11/30 16:50:02 Shutdown Server ...2
2022/11/30 16:50:02 Shutdown Server ...1

Process finished with the exit code 0