加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

【golang】信号捕捉和处理

发布时间:2020-12-16 18:43:00 所属栏目:大数据 来源:网络整理
导读:捕捉和处理信号可以实现优雅start和restart等。golang的signal提供了相关的方法。这里是一个模板,目录结构: ├── sig│ └── sig.go└── test.go 先看如何调用: 1.new出一个对象 2.register信号与对应的处理函数 3.定义os.Signal类型的channel,调

捕捉和处理信号可以实现优雅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: %vn",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 : %vn",stopFlag_)
    case syscall.SIGUSR2: // run
        formerFlag := stopFlag_
        stopFlag_ = false
        fmt.Printf("stopping Status changed from %v to %vn",formerFlag,stopFlag_)
    case syscall.SIGQUIT: // stop
        formerFlag := stopFlag_
        stopFlag_ = true
        fmt.Printf("stopping Status changed from %v to %vn",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")
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读