捕获Ctrl + C中断 优雅的退出程序 golang

捕获Ctrl + C中断 优雅的退出程序

Gracefully terminate a program in Go

// Notify方法将signal发送到channel,
func Notify(c chan<- os.Signal, sig ...os.Signal)
// 初始化一个接受os.Signal的通道
c := make(chan os.Signal)
// 调用Notify方法,绑定signal到channel,一旦有信号到达,signal会发送到channel中
signal.Notify(c, os.Interrupt)
  1. 代码实现在命令行每隔200ms打印字符"#",使用time.Ticker实现每隔2s打印完整一次
  2. task有一个close的channel,用来接受停止信号
  3. 实例化一个os.Signal来接受诸如ctrl+c的停止信号
  4. 使用sync.WaitGroup来组织多个goroutine的调度
package main

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"time"
)

type Task struct {
	closed chan struct{}
	wg     sync.WaitGroup
	ticker *time.Ticker
}

func (t *Task) Run() {
	for {
		select {
		case <-t.closed:
			return
		case <-t.ticker.C:
			handle()
		}
	}
}

func (t *Task) Stop() {
	close(t.closed)
}

func handle() {
	for i := 0; i < 5; i++ {
		fmt.Print("#")
		time.Sleep(time.Millisecond * 200)
	}
	fmt.Println()
}

func main() {
	task := &Task{
		closed: make(chan struct{}),
		ticker: time.NewTicker(time.Second * 2),
	}

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt)

	task.wg.Add(1)
	go func() { defer task.wg.Done(); task.Run() }()

	select {
	case sig := <-c:
		fmt.Printf("Got %s signal. Aborting...
", sig)
		task.Stop()
	}
  task.wg.Wait()
}
原文地址:https://www.cnblogs.com/linyihai/p/10805716.html