How to handle signals in Golang?


Before discussing signals and how to handle them, let's talk about a common scenario of creating a signal. A signal can be passed from the terminal, by either terminating the program with the help of CTRL+C or we can by default call the Exit() function that the os package provides us with.

Example 1

Let's consider an example where we will call the os.Exit() function just after a function declaration that has been deferred.

Consider the code shown below.

package main

import (
   "fmt"
   "os"
   "time"
)

func main() {
   defer func() {
      fmt.Println("Inside the deferred function()")
   }()

   fmt.Println("Inside the main function")
   time.Sleep(1 * time.Second)
   os.Exit(1)
}

In the above code, we are calling the os.Exit() function which will not provide the chance to the deferred anonymous function to execute, as the program will exit.

Output

If we run the above code with the command go run main.go then we will get the following output in the terminal.

Inside the main function
Program exited: status 1.

Another signal that we might get is that we terminate the process with the help of CTRL+C.

How to handle a signal in Golang

We did talk about the different ways in which a signal can be passed to the program. Now, let's talk about how we can deal with these signals and handle them in Go.

In order to gracefully handle these signals, we can use a channel that will be of type os.Signal which will be blocking in nature. Then we will use the Notify() function, inside which we can pass the different types of signals that we are expecting, like os.Interrupt and syscall.SIGTERM.

Example 2

Consider the code shown below.

package main

import (
   "fmt"
   "os"
   "os/signal"
   "syscall"
)

func main() {
   sigChannel := make(chan os.Signal, 1)
   signal.Notify(sigChannel, os.Interrupt, syscall.SIGTERM)

   fmt.Println("Try pressing CTRL + C to handle the interrupt")

   select {
   case <-sigChannel:
      fmt.Println("The interrupt got handled")
      os.Exit(0)
   }
}

In the above code, we created a buffered channel with capacity 1 and then we are calling the Notify() function.

Output

If we run the above code with the command go run main.go and then press CTRL + C, then we will get the following output in the terminal.

Try pressing CTRL + C to handle the interrupt
The interrupt got handled

Updated on: 01-Nov-2021

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements