Golang-信号处理

当进程正在执行时,通常会通过kill -9 PID来将其结束,这个时候的操作就是向进程传递一个信号,进程收到信号就会进行对应的操作,9就是最常用到的杀掉进程操作。

信号类型

信号 动作 说明
SIGHUP 1 Term 终端控制进程结束(终端连接断开)
SIGINT 2 Term 用户发送INTR字符(Ctrl+C)触发
SIGQUIT 3 Core 用户发送QUIT字符(Ctrl+/)触发
SIGILL 4 Core 非法指令(程序错误、试图执行数据段、栈溢出等)
SIGABRT 6 Core 调用abort函数触发
SIGFPE 8 Core 算术运行错误(浮点运算错误、除数为零等)
SIGKILL 9 Term 无条件结束程序(不能被捕获、阻塞或忽略)
SIGSEGV 11 Core 无效内存引用(试图访问不属于自己的内存空间、对只读内存空间进行写操作)
SIGPIPE 13 Term 消息管道损坏(FIFO/Socket通信时,管道未打开而进行写操作)
SIGALRM 14 Term 时钟定时信号
SIGTERM 15 Term 结束程序(可以被捕获、阻塞或忽略)
SIGUSR1 30,10,16 Term 用户保留
SIGUSR2 31,12,17 Term 用户保留
SIGCHLD 20,17,18 Ign 子进程结束(由父进程接收)
SIGCONT 19,18,25 Cont 继续执行已经停止的进程(不能被阻塞)
SIGSTOP 17,19,23 Stop 停止进程(不能被捕获、阻塞或忽略)
SIGTSTP 18,20,24 Stop 停止进程(可以被捕获、阻塞或忽略)
SIGTTIN 21,21,26 Stop 后台程序从终端中读取数据时触发
SIGTTOU 22,22,27 Stop 后台程序向终端中写数据时触发

Golang中信号的应用

一个简单的例子:

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)
}
}

首先make一个channel,它的类型是os.Signal,然后用signal.Notify来注册,这样当有信号传入进程时,c就可以接收到,同时通过channel机制执行接收到数据后的操作。

END