在Golang中处理信号以优雅地终止操作(附示例)

93 阅读2分钟

在这个例子中,我们将捕捉某些信号,并在终止循环操作前等待3秒。

例子

package main

import (
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"internal/app"
)

func main() {
	go shutdownHandler()

	app.App{Count: 100, Sleep: 300}.Run()
}

// shutdownHandler triggers application shutdown.
func shutdownHandler()  {
	// signChan channel is used to transmit signal notifications.
	signChan := make(chan os.Signal, 1)
	// Catch and relay certain signal(s) to signChan channel.
	signal.Notify(signChan, os.Interrupt, syscall.SIGTERM)

	// Blocking until a signal is sent over signChan channel. Progress to
	// next line after signal
	sig := <-signChan

	log.Println("cleanup started with", sig, "signal")
	time.Sleep(time.Duration(3) * time.Second)
	log.Println("cleanup completed in", 3, "seconds")

	os.Exit(1)
}
package app

import (
	"log"
	"time"
)

type App struct {
	Count int
	Sleep int
}

func (a App) Run() {
	for i := 1; i < a.Count; i++ {
		log.Println(i, "- sleeping", a.Sleep, "milliseconds")

		time.Sleep(time.Duration(a.Sleep) * time.Millisecond)
	}
}

测试

2020/03/16 21:47:25 1 - sleeping 300 milliseconds
2020/03/16 21:47:25 2 - sleeping 300 milliseconds
2020/03/16 21:47:25 3 - sleeping 300 milliseconds
2020/03/16 21:47:26 4 - sleeping 300 milliseconds
2020/03/16 21:47:26 5 - sleeping 300 milliseconds
2020/03/16 21:47:26 6 - sleeping 300 milliseconds
^C
2020/03/16 21:47:26 cleanup started with interrupt signal
2020/03/16 21:47:26 7 - sleeping 300 milliseconds
2020/03/16 21:47:27 8 - sleeping 300 milliseconds
2020/03/16 21:47:27 9 - sleeping 300 milliseconds
2020/03/16 21:47:27 10 - sleeping 300 milliseconds
2020/03/16 21:47:28 11 - sleeping 300 milliseconds
2020/03/16 21:47:28 12 - sleeping 300 milliseconds
2020/03/16 21:47:28 13 - sleeping 300 milliseconds
2020/03/16 21:47:29 14 - sleeping 300 milliseconds
2020/03/16 21:47:29 15 - sleeping 300 milliseconds
2020/03/16 21:47:29 16 - sleeping 300 milliseconds
2020/03/16 21:47:29 cleanup completed in 3 seconds
exit status 1