微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【golang】信号捕捉和处理

捕捉和处理信号可以实现优雅start和restart等。golang的signal提供了相关的方法。这里是一个模板,目录结构:

├── sig
│ └── sig.go
└── test.go

先看如何调用

1.new出一个对象

2.register信号与对应的处理函数

3.定义os.Signal类型的channel,调用signal.Notify

4.for+select循环,原有逻辑放在default分支中。


package main
 
import (
    . "./sig"
 
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)
 
var stopFlag_ bool
 
func main() {
 
    sigHandler := SignalSetNew()
    sigHandler.Register(syscall.SIGQUIT,sigHandlerFunc)
    sigHandler.Register(syscall.SIGUSR1,sigHandlerFunc)
    sigHandler.Register(syscall.SIGUSR2,sigHandlerFunc)
    sigChan := make(chan os.Signal,10)
    signal.Notify(sigChan)
 
    for true {
        select {
        case sig := <-sigChan:
            err := sigHandler.Handle(sig,nil)
            if err != nil {
                fmt.Printf("[ERROR] unkNown signal received: %v\n",sig)
                os.Exit(1)
            }
        default:
            time.Sleep(time.Duration(3) * time.Second)
        }
    }
}
 
func sigHandlerFunc(s os.Signal,arg interface{}) {
    switch s {
    case syscall.SIGUSR1: // check
        fmt.Printf("stopping Status : %v\n",stopFlag_)
    case syscall.SIGUSR2: // run
        formerFlag := stopFlag_
        stopFlag_ = false
        fmt.Printf("stopping Status changed from %v to %v\n",formerFlag,stopFlag_)
    case syscall.SIGQUIT: // stop
        formerFlag := stopFlag_
        stopFlag_ = true
        fmt.Printf("stopping Status changed from %v to %v\n",stopFlag_)
    }
}

sig包(sig/sig.go)的定义:
package sig
 
import (
    "fmt"
    "os"
)
 
type SignalHandler func(s os.Signal,arg interface{})
 
type SignalSet struct {
    m map[os.Signal]SignalHandler
}
 
func SignalSetNew() *SignalSet {
    ss := new(SignalSet)
    ss.m = make(map[os.Signal]SignalHandler)
    return ss
}
 
func (set *SignalSet) Register(s os.Signal,handler SignalHandler) {
    if _,found := set.m[s]; !found {
        set.m[s] = handler
    }
}
 
func (set *SignalSet) Handle(sig os.Signal,arg interface{}) (err error) {
    if _,found := set.m[sig]; found {
        set.m[sig](sig,arg)
        return nil
    } else {
        return fmt.Errorf("No handler available for signal %v",sig)
    }
    panic("won't reach here")
}

原文地址:https://www.jb51.cc/go/190408.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐