【golang】信号捕捉和处理

fall221 · · 3916 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

    捕捉和处理信号可以实现优雅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", formerFlag, 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")
}





有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:fall221

查看原文:【golang】信号捕捉和处理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3916 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传