随笔 - 941, 文章 - 0, 评论 - 249, 阅读 - 348万

导航

< 2025年4月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

Golang的 signal

Posted on   蝈蝈俊  阅读(1832)  评论(0编辑  收藏  举报

在实际项目中我们可能有下面的需求:
1、修改了配置文件后,希望在不重启进程的情况下重新加载配置文件;
2、当用 Ctrl + C 强制关闭应用后,做一些必要的处理;

这时候就需要通过信号传递来进行处理了。golang中对信号的处理主要使用os/signal包中的两个方法:一个是notify方法用来监听收到的信号;一个是 stop方法用来取消监听。

 

监听信号

notify方法原型
func Notify(c chan<- os.Signal, sig ...os.Signal)
第一个参数表示接收信号的管道
第二个及后面的参数表示设置要监听的信号,如果不设置表示监听所有的信号。

 

下面是一个非常简单地例子:

package main

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

func main() {
    c := make(chan os.Signal)
    signal.Notify(c)

    //signal.Notify(c, syscall.SIGHUP, syscall.SIGUSR2)  //监听指定信号

    s := <-c //阻塞直至有信号传入
    fmt.Println("get signal:", s)
}

执行效果:

当按下 ctrl +c 键时:

image

上面的代码过于简单,一般我们会是用下面代码的方式来处理的。

package main

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

func main() {
    go signalListen()
    time.Sleep(time.Hour)
}

func signalListen() {
    c := make(chan os.Signal)
    signal.Notify(c)
    for {
        s := <-c
        //收到信号后的处理,这里只是输出信号内容,可以做一些更有意思的事
        fmt.Println("get signal:", s)
        os.Exit(1)
    }
}

执行效果:

这是在进入应用后, 按了四次回车,然后再按 Ctrl +C 的执行效果:

image

 

停止监听

package main

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

func main() {
    c := make(chan os.Signal)
    signal.Notify(c)

    //当调用了该方法后,下面的for循环内<-c接收到一个信号就退出了。
    signal.Stop(c)

    for {
        s := <-c
        fmt.Println("get signal:", s)
    }
}

执行效果:

image

 

golang中处理信号非常简单,但是关于信号本身需要了解的还有很多,建议可以参考《Unix高级编程》中的信号篇章。

 

 

参考资料:

golang信号signal的处理
http://www.01happy.com/golang-signal/

Go中的系统Signal处理
http://tonybai.com/2012/09/21/signal-handling-in-go/

编辑推荐:
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
阅读排行:
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析
· 上周热点回顾(3.24-3.30)
点击右上角即可分享
微信分享提示