シグナルを受け取ってgorutineの終了を待ってからプログラムを終了する
件名の通り。
DBアクセスなどプログラム終了前に走り切らせたい処理を定期起動するプログラムでは、終了のためのシグナルを受け取ったらその定期起動するためのgoroutineを終わらせてからプログラムを終了したい。
package main import ( "context" "log" "os" "os/signal" "time" "sync" "syscall" ) func main() { var wg sync.WaitGroup ctx, cancel := context.WithCancel(context.Background()) wg.Add(1) go func() { defer wg.Done() loop(ctx) }() log.Println("シグナルを受け付ける") sigChan := make(chan os.Signal, 1) signal.Notify(sigChan) flag := true for flag { sig:= <-sigChan log.Println("シグナルを受け取った", sig) switch sig { case syscall.SIGURG: log.Println("無視") default: log.Println("シグナル待ちをやめる") flag = false } } log.Println("goroutineを停止する") cancel() log.Println("goroutineの終了を待つ") wg.Wait() } func loop(ctx context.Context) { for { select { case <-ctx.Done(): log.Println("goroutineのキャンセルを検出!") return default: log.Println(time.Now().Local(), "何かしらの処理") time.Sleep(time.Second) } } }