通过信号量可以监听到系统发出的关停,程序意外关闭、退出、重启等,可以记录相关信息和退出前的操作。
系统支持的信号类型,其中 1~31项为不可靠信号, 34~64为可靠信号
1.SIGHUP:当终端断开时,将发送该信号给终端控制进程。SIGHUP信号还可用于守护进程。
2.SIGINT:当用户键入终端中断字符(如:Ctrl + C)终端驱动程序将发送该信号给前台进程组。该信号默认行为是终止进程。
3.SIGQUIT:当用户在键盘键入退出字符(如Ctrl+\)时,该信号将发往前台进程组。默认情况下,该信号终止进程,并生成可用于调试的核心转储文件。当进程陷入无限循环或者不在响应,使用该信号很合适。
4.SIGILL:进程试图非法执行机器语言指令,系统将向该进程发送该信号。
5.SIGTRAP:该信号用来实现断点调试功能以及strace命令所执行的跟踪系统调用功能。
6.SIGABRT:当进程调用abort函数时,系统向该进程发送该信号。默认情况下,该信号会终止进程,并产生核心转储文件。
7.SIGBUS:总线错误,表示发生了某种内存访问错误。当使用mmap()所创建的内存映射时,如果试图访问的地址超出了底层内存映射文件的结尾,会产生该错误。
8.SIGFPE:在发生致命的算术运算错误时发出. 不仅包括浮点运算错误, 还包括溢出及除数为0等其它所有的算术的错误。
9.SIGKILL:此信号为必杀信号,处理器程序无法阻塞、忽略或者捕获,故而总能杀死进程(僵尸进程除外)。
10.SIGUSR1:用户自定义信号,内核绝不会为进程产生该信号。
11.SIGSEGV:试图访问未分配给自己的内存, 或试图往没有写权限的内存地址写数据.
12.SIGUSR2:同SIGUSR1描述。
13.SIGPIPE:当某一进程试图向管道,FIFO或套接字写入信息时,如果这些设备并无相应的阅读进程,系统将产生该信号。(管道破裂)
14.SIGALRM:经调用alarm()或setitimer()而设置的实时定时器一旦到期,内核将产生该信号。
15.SIGTERM:这是用来终止进程的标准信号,也是kill和killall命令所发送的默认信号。用户经常会使用kil -9显示向进程发送SIGKILL信号,然而这一做法通常是错误的。精心设计的应用程序应当为SIGTERM信号设置处理器程序,以便于其能够预先清理临时文件和释放资源,做到全身而退。发送SIGKILL信号可以杀掉某个进程,从而绕开了SIGTERM的信号处理程序。因此,总是应该首先尝试使用SIGTERM信号来终止进程,而把SIGKILL信号作为最后手段,去对付那些失控的进程。
16.SIGSTKFLT:linux对该信号做了定义,但并未加以使用。
17.SIGCHLD:当父进程的某一子进程退出时,内核将向父进程发送该信号。
18.SIGCONT:该信号发送给已停止的进程,进程将恢复运行。当接收信号的进程当前处于非停止状态 时,默认情况下将忽略该信号。
19.SIFSTOP:进程收到该信号将停止运行,处理器程序无法将其阻塞、忽略或者捕获,故而总能停止进程。
20.SIGTSTP:作业控制的停止信号,当用户在键盘输入挂起字符(如:Ctrl+Z)时,将发送该信号给前台进程组,使其停止运行。(该信号可以被处理和忽略)
21.SIGTTIN:在作业控制shell下运行时,若后台进程组试图对终端进行read()操作,终端驱动程序则将该进程组发送该信号。该信号默认将停止进程。
22.SIGTTOU:该信号与SIGTTIN类似,但在写终端(或修改终端模式)时收到。
23.SIGURG:系统发送该信号给一个进程,表示套接字上存在带外(紧急)数据。
24.SIGXCPU:当进程的CPU时间超出对应的资源限制时,将发送此信号给进程。
25.SIGXFSZ:如果进程试图增大文件而突破对进程文件大小的资源限制时,将发送该信号给进程。
26.SIGVTALRM:虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间。
27.SIGPROF:类似于SIGALRM/SIGVTALRM, 但包括该进程用的CPU时间以及系统调用的时间.
28.SIGWINCH:窗口大小改变时发出该信号。
29.SIGIO:文件描述符准备就绪, 可以开始进行输入/输出操作。
30.SIGPWR:电源故障信号。
31.SIGSYS:如果进程发起的系统调用有误,将产生该信号。
监听SIGINT和SIGKILL信号
ctrl+c 产生了一个 SIGINT(中断信号)。
kill 9发送一个 SIGKILL信号 终止进程的信号来结束进程。
func main() {
fmt.Println("start")
go func() {
for {
time.Sleep(time.Second)
fmt.Println(time.Now().Unix())
}
}()
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Println("处理关闭逻辑")
fmt.Println("关闭成功")
}