信号类型
个平台的信号定义或许有些不同。下面列出了POSIX中定义的信号。
Linux 使用34-64信号用作实时系统中。
命令man 7 signal
提供了官方的信号介绍。
在POSIX.1-1990标准中定义的信号列表
信号 | 值 | 动作 | 说明 |
---|---|---|---|
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 | 后台程序向终端中写数据时触发 |
在SUSv2和POSIX.1-2001标准中的信号列表:
信号 | 值 | 动作 | 说明 |
---|---|---|---|
SIGTRAP | 5 | Core | Trap指令触发(如断点,在调试器中使用) |
SIGBUS | 0,7,10 | Core | 非法地址(内存地址对齐错误) |
SIGPOLL | Term | Pollable event (Sys V). Synonym for SIGIO | |
SIGPROF | 27,27,29 | Term | 性能时钟信号(包含系统调用时间和进程占用cpu的时间) |
SIGSYS | 12,31,12 | Core | 无效的系统调用(SVr4) |
SIGURG | 16,23,21 | Ign | 有紧急数据到达Socket(4.2BSD) |
SIGVTALRM | 26,26,28 | Term | 虚拟时钟信号(进程占用cpu的时间)(4.2BSD) |
SIGXcpu | 24,24,30 | Core | 超过cpu时间资源限制(4.2BSD) |
SIGXFSZ | 25,25,31 | Core | 超过文件大小资源限制(4.2BSD) |
Go中的Signal发送和处理
有时候我们想在Go程序中处理Signal信号,比如收到SIGTERM
信号后优雅的关闭程序(参看下一节的应用)。
Go信号通知机制可以通过往一个channel中发送os.Signal
实现。
首先我们创建一个os.Signal channel,然后使用signal.Notify
注册要接收的信号。
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
@H_85_403@
27
28
29
30
@H_502_411@
31
32
33
34
35
36
37
|
packagemain
import
"fmt"
"os"
"os/signal"
"syscall"
funcmain() {
// Go signal notification works by sending `os.Signal`
// values on a channel. We'll create a channel to
// receive these notifications (we'll also make one to
sigs := make(chanos.Signal,1)
done := make(chanbool,1)
// `signal.Notify` registers the given channel to
// receive notifications of the specified signals.
signal.Notify(sigs,syscall.SIGINT,syscall.SIGTERM)
// This goroutine executes a blocking receive for
// signals. When it gets one it'll print it out
// and then notify the program that it can finish.
gofunc() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
// The program will wait here until it gets the
// expected signal (as indicated by the goroutine
// above sending a value on `done`) and then exit.
fmt.Println(
"awaiting signal"
)
<-done
"exiting"
)
}
|
执行这个程序,敲入ctrl-C会发送信号。 此程序接收到这个信号后会打印退出。go run main.goSIGINT