30.2 os、signal 信号处理

一个运行良好的程序在退出(正常退出或者强制退出,如ctrl+c,kill等)时是可以执行一段清理代码,将收尾工作做完后再真正退出。一般采用系统Signal来通知系统退出,如kill pid。在程序中针对一些系统信号设置了处理函数,当收到信号后,会执行相关清理程序或通知各个子进程做自清理。

Go的系统信号处理主要涉及os包、os.signal包以及syscall包。其中最主要的函数是signal包中的Notify函数:func Notify(c chan<- os.Signal, sig …os.Signal)

该函数会将进程收到的系统Signal转发给channel c。如果没有传入sig参数,那么Notify会将系统收到的所有信号转发给channel c。

Notify会根据传入的os.Signal,监听对应Signal信号,Notify()方法会将接收到对应os.Signal往一个channel c中发送。

下面代码以 syscall.SIGUSR2 信息为例,说明了具体实现:

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

关于信号有关信息,有兴趣建议可以参考《UNIX高级编程》。其他更多Signal信号类型,请参看相关手册。

os包中其他的功能还有很多,这里就不一一介绍了。