golang优雅退出进程

2018-06-19 09:05:16 george518 ...

/************************************************************
** @Description: signal
** @Author: george hao
** @Date:   2018-06-12 17:12
** @Last Modified by:  george hao
** @Last Modified time: 2018-06-12 17:12
*************************************************************/
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)
    ts := make(chan int)

    cs := CreateGeneral(ts)
    go func() {
        for s := range c {
            switch s {
            case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
                fmt.Println("退出", s)
                ts <- 1
                ExitFunc(cs)
            case syscall.SIGUSR1:
                fmt.Println("usr1", s)
            case syscall.SIGUSR2:
                fmt.Println("usr2", s)
            default:
                fmt.Println("other", s)
            }
        }
    }()

    fmt.Println("进程启动...")
    Worker(cs)
}

func CreateGeneral(ts chan int) chan int {
    sum := 0
    c := make(chan int, 100)

    stop := 0
    go func() {
        for {

            select {
            case n := <-ts:
                fmt.Println(n, "要close了")
                if n == 1 {
                    stop = n
                }
            default:
                time.Sleep(1 * time.Second)
                sum++
                c <- sum
            }

            if stop == 1 {
                close(c)
                break
            }
        }

    }()
    return c
}

func Worker(c chan int) {
    for {
        time.Sleep(2 * time.Second)
        fmt.Println(<-c, len(c))
    }
}

func ExitFunc(cs chan int) {
    fmt.Println("开始退出...")
    fmt.Println("执行清理...")

    for {
        if len(cs) == 0 {
            fmt.Println("结束退出...")
            time.Sleep(1 * time.Second)
            break
        }
    }
    os.Exit(0)

}

结果:

进程启动…
1 0
2 1
3 2
4 3
退出 interrupt
1 要close了
开始退出…
执行清理…
5 4
6 3
7 2
8 1
9 0
结束退出…

相似文章