Golang signal processing and graceful exit daemon

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Signal processing in the Golang

    • Signal type
个平台的信号定义或许有些不同。下面列出了POSIX中定义的信号。Linux 使用34-64信号用作实时系统中。命令 man signal 提供了官方的信号介绍。在POSIX.1-1990标准中定义的信号列表
Signal value Action Description
SIGHUP 1 Term Terminal Control process End (terminal connection disconnected)
SIGINT 2 Term User sends Intr character (CTRL + C) trigger
Sigquit 3 Core User sends the Quit character (ctrl+/) trigger
Sigill 4 Core Illegal instruction (program error, attempt to execute data segment, stack overflow, etc.)
Sigabrt 6 Core Call the Abort function to trigger
SIGFPE 8 Core Arithmetic run error (floating-point arithmetic error, divisor is zero, etc.)
SIGKILL 9 Term Unconditional End Program (cannot be captured, blocked, or ignored)
SIGSEGV 11 Core Invalid memory reference (attempting to access memory space that does not belong to itself, write to read-only memory space)
Sigpipe 13 Term Message pipeline Corruption (Fifo/socket communication, the pipeline is not open and writes)
Sigalrm 14 Term Clock timing Signal
SIGTERM 15 Term End program (can be captured, blocked, or ignored)
SIGUSR1 30,10,16 Term User Retention
SIGUSR2 31,12,17 Term User Retention
SIGCHLD 20,17,18 Ign Child process End (received by parent process)
Sigcont 19,18,25 Cont Continue execution of stopped processes (cannot be blocked)
SIGSTOP 17,19,23 Stop Stop a process (cannot be caught, blocked, or ignored)
Sigtstp 18,20,24 Stop Stop a process (can be caught, blocked, or ignored)
Sigttin 21,21,26 Stop Triggers when the daemon reads data from the terminal
Sigttou 22,22,27 Stop Triggers when a background program writes data to the terminal
    • List of signals in the SUSV2 and posix.1-2001 standards:
Signal value Action Description
SIGTRAP 5 Core TRAP instruction triggers (such as breakpoints, used in the debugger)
Sigbus 0,7,10 Core Illegal address (memory address alignment error)
Sigpoll Term Pollable event (Sys V). Synonym for SIGIO
Sigprof 27,27,29 Term Performance clock signal (includes system call time and process consuming CPU time)
Sigsys 12,31,12 Core Invalid system call (SVR4)
Sigurg 16,23,21 Ign Emergency data arrives at socket (4.2BSD)
Sigvtalrm 26,26,28 Term Virtual clock signal (process consumes CPU time) (4.2BSD)
Sigxcpu 24,24,30 Core CPU time resource limit exceeded (4.2BSD)
Sigxfsz 25,25,31 Core File size resource limit exceeded (4.2BSD)
第1列为信号名;第2列为对应的信号值,需要注意的是,有些信号名对应着3个信号值,这是因为这些信号值与平台相关,将man手册中对3个信号值的说明摘出如下,the first one is usually valid for alpha and sparc, the middle one for i386, ppc and sh, and the last one for mips.第3列为操作系统收到信号后的动作,Term表明默认动作为终止进程,Ign表明默认动作为忽略该信号,Core表明默认动作为终止进程同时输出core dump,Stop表明默认动作为停止进程。第4列为对信号作用的注释性说明,浅显易懂,这里不再赘述。需要特别说明的是,SIGKILL和SIGSTOP这两个信号既不能被应用程序捕获,也不能被操作系统阻塞或忽略。
    • The difference between kill PID and Kill-9 PID
kill pid的作用是向进程号为pid的进程发送SIGTERM(这是kill默认发送的信号),该信号是一个结束进程的信号且可以被应用程序捕获。若应用程序没有捕获并响应该信号的逻辑代码,则该信号的默认动作是kill掉进程。这是终止指定进程的推荐做法。
kill -9 pid则是向进程号为pid的进程发送SIGKILL(该信号的编号为9),从本文上面的说明可知,SIGKILL既不能被应用程序捕获,也不能被阻塞或忽略,其动作是立即结束指定进程。通俗地说,应用程序根本无法“感知”SIGKILL信号,它在完全无准备的情况下,就被收到SIGKILL信号的操作系统给干掉了,显然,在这种“暴力”情况下,应用程序完全没有释放当前占用资源的机会。事实上,SIGKILL信号是直接发给init进程的,它收到该信号后,负责终止pid指定的进程。在某些情况下(如进程已经hang死,无法响应正常信号),就可以使用kill -9来结束进程。
若通过kill结束的进程是一个创建过子进程的父进程,则其子进程就会成为孤儿进程(Orphan Process),这种情况下,子进程的退出状态就不能再被应用进程捕获(因为作为父进程的应用程序已经不存在了),不过应该不会对整个linux系统产生什么不利影响。
    • How the app gracefully exits
Linux Server端的应用程序经常会长时间运行,在运行过程中,可能申请了很多系统资源,也可能保存了很多状态,在这些场景下,我们希望进程在退出前,可以释放资源或将当前状态dump到磁盘上或打印一些重要的日志,也就是希望进程优雅退出(exit gracefully)。
从上面的介绍不难看出,优雅退出可以通过捕获SIGTERM来实现。具体来讲,通常只需要两步动作:1)注册SIGTERM信号的处理函数并在处理函数中做一些进程退出的准备。信号处理函数的注册可以通过signal()或sigaction()来实现,其中,推荐使用后者来实现信号响应函数的设置。信号处理函数的逻辑越简单越好,通常的做法是在该函数中设置一个bool型的flag变量以表明进程收到了SIGTERM信号,准备退出。2)在主进程的main()中,通过类似于while(!bQuit)的逻辑来检测那个flag变量,一旦bQuit在signal handler function中被置为true,则主进程退出while()循环,接下来就是一些释放资源或dump进程当前状态或记录日志的动作,完成这些后,主进程退出。

signal send and process in go

    • The processing of signals in Golang mainly uses the two methods in the Os/signal package:
    • The Notify method is used to listen for incoming signals.
    • The Stop method is used to cancel the listener

1. Monitor all Signals

package mainimport (    "fmt"    "os"    "os/signal")// 监听全部信号func main()  {    //合建chan    c := make(chan os.Signal)    //监听所有信号    signal.Notify(c)    //阻塞直到有信号传入    fmt.Println("启动")    s := <-c    fmt.Println("退出信号", s)}
启动go run example-1.go启动ctrl+c退出,输出退出信号 interruptkill pid 输出退出信号 terminated

2. Monitor the specified signal

package mainimport (    "fmt"    "os"    "os/signal"    "syscall")// 监听指定信号func main()  {    //合建chan    c := make(chan os.Signal)    //监听指定信号 ctrl+c kill    signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGUSR1, syscall.SIGUSR2)    //阻塞直到有信号传入    fmt.Println("启动")    //阻塞直至有信号传入    s := <-c    fmt.Println("退出信号", s)}
启动go run example-2.go启动ctrl+c退出,输出退出信号 interruptkill pid 输出退出信号 terminatedkill -USR1 pid 输出退出信号 user defined signal 1kill -USR2 pid 输出退出信号 user defined signal 2

3. Gracefully exit the Go daemon

  Package Mainimport ("FMT" "OS" "Os/signal" "Syscall" "Time")//Graceful exit Go daemon func main () {//Create Listen quit Chan c: = Make (chan os. Signal)//monitor the specified signal CTRL + C kill Signal. Notify (c, Syscall. SIGHUP, Syscall. SIGINT, Syscall. SIGTERM, Syscall. Sigquit, Syscall. SIGUSR1, Syscall. SIGUSR2) go func () {for s: = range C {Switch s {case Syscall. SIGHUP, Syscall. SIGINT, Syscall. SIGTERM, Syscall. Sigquit:fmt. Println ("Exit", s) exitfunc () Case Syscall. Sigusr1:fmt. Println ("USR1", s) case Syscall. Sigusr2:fmt. Println ("USR2", s) default:fmt. Println ("Other", s)}}} () Fmt. PRINTLN ("Process start ...") Sum: = 0 for {sum++ fmt. Println ("sum:", sum) time. Sleep (time. Second)}}func Exitfunc () {fmt. Println ("Start exiting ...") fmt. Println ("Perform cleanup ...") fmt. Println ("End exit ...") OS. Exit (0)}  
kill -USR1 pid 输出usr1 user defined signal 1kill -USR2 pid usr2 user defined signal 2kill pid 退出 terminated开始退出...执行清理...结束退出...
执行输出go run example-3.go进程启动...sum: 1sum: 2sum: 3sum: 4sum: 5sum: 6sum: 7sum: 8sum: 9usr1 user defined signal 1sum: 10sum: 11sum: 12sum: 13sum: 14usr2 user defined signal 2sum: 15sum: 16sum: 17退出 terminated开始退出...执行清理...结束退出...

Reference

http://www.cnblogs.com/jkkkk/p/6180016.htmlhttp://blog.csdn.net/zzhongcy/article/details/50601079https://www.douban.com/note/484935836/https://gist.github.com/reiki4040/be3705f307d3cd136e85#file-signal-go-L1
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.