Go语言 signal.Notify 信号量的使用(优雅关闭进程资源)

Posted 张志翔ۤ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言 signal.Notify 信号量的使用(优雅关闭进程资源)相关的知识,希望对你有一定的参考价值。

        go中的信号量:

信号动作说明
SIGHUP1Term终端控制进程结束(终端连接断开)
SIGINT2Term用户发送INTR字符(Ctrl+C)触发
SIGQUIT3Core用户发送QUIT字符(Ctrl+/)触发
SIGILL4Core非法指令(程序错误、试图执行数据段、栈溢出等)
SIGABRT6Core调用abort函数触发
SIGFPE8Core算术运行错误(浮点运算错误、除数为零等)
SIGKILL9Term无条件结束程序(不能被捕获、阻塞或忽略)
SIGSEGV11Core无效内存引用(试图访问不属于自己的内存空间、对只读内存空间进行写操作)
SIGPIPE13Term消息管道损坏(FIFO/Socket通信时,管道未打开而进行写操作)
SIGALRM14Term时钟定时信号
SIGTERM15Term结束程序(可以被捕获、阻塞或忽略)
SIGUSR130,10,16Term用户保留
SIGUSR231,12,17Term用户保留
SIGCHLD20,17,18Ign子进程结束(由父进程接收)
SIGCONT19,18,25Cont继续执行已经停止的进程(不能被阻塞)
SIGSTOP17,19,23Stop停止进程(不能被捕获、阻塞或忽略) SIGTSTP 18,20,24 Stop 停止进程(可以被捕获、阻塞或忽略) SIGTTIN 21,21,26 Stop 后台程序从终端中读取数据时触发 SIGTTOU 22,22,27 Stop 后台程序向终端中写数据时触发

        有些信号名对应着3个信号值,这是因为这些信号值与平台相关,SIGKILL和SIGSTOP这两个信号既不能被应用程序捕获,也不能被操作系统阻塞或忽略。

        优雅地退出程序

        在长时间的程序运行过程中,可能有大量的系统资源被申请,无论在以何种方式退出前,他们应该及时将这些资源释放并将状态输出到日志中方便调试和排错。

        signal.Notify方法监听和捕获信号量

func Notify(c chan<- os.Signal, sig …os.Signal)

        首先定义一个 c 传递信号量,然后说明那些信号量是需要被捕获的,信号量没有捕获到就会阻塞在这里(不填的话就默认捕获任何信号量):

c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

        监听信号量输出(只要上述三种信号量有输出,就会停止阻塞,执行代码):

func terminal() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	select {
	case <-c:
		log.Infof("stop signal caught, pid[%d] stopping...", os.Getpid())
	}
	http.Shutdown()
	rpc.Shutdown()
	log.Info("transfer has stopped successfully !!!")
}

        还有另一种方式可以根据不同信号量捕获做不同的逻辑处理,代码如下:

func terminal() {
	sc := make(chan os.Signal, 1)
    signal.Notify(sc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	select {
	switch sig {
        case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
			log.Panic("SIGQUIT")
		case syscall.SIGHUP:
			log.Panic("SIGHUP")
		case syscall.SIGHUP:
			log.Panic("SIGINT")
    }
	http.Shutdown()
	rpc.Shutdown()
	log.Info("transfer has stopped successfully !!!")
}


        terminal 方法放到 main.go 的最后一行执行,一直阻塞直到捕获到对应信号量做终止进程的相关后续处理。

        到此 Go语言 signal.Notify 优雅关闭进程资源介绍完成。

以上是关于Go语言 signal.Notify 信号量的使用(优雅关闭进程资源)的主要内容,如果未能解决你的问题,请参考以下文章

GO学习笔记-监听OS信号

从源码剖析Go语言基于信号抢占式调度

Go语言协程并发---管道信号量应用

go语言快速入门 IPC之管道通信 8

Go语言-信号os.Interrupt和信号syscall.SIGTERM的应用

Go中多协程协作之sync.Cond