In a Go program, you can handle signals such as SIGINT (Ctrl+C) and SIGTERM using the os package. Here's how you can handle these signals:
import (
"os"
"os/signal"
"syscall"
)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
The above code creates a channel interrupt
to receive the SIGINT and SIGTERM signals. The signal.Notify()
function is used to register the channel to receive these signals.
go func() {
// Your main program logic goes here
// For example, running a server
// ...
}()
By running your main program logic in a separate goroutine, it allows you to handle signals in a controlled manner.
<-interrupt
This code will block the execution of your program until a signal is received on the interrupt
channel.
// Perform necessary cleanup, graceful shutdown, etc.
// ...
// Exit the program
os.Exit(0)
You can perform any necessary cleanup or graceful shutdown operations when a signal is received. After that, you can exit the program using os.Exit()
.
Here's an example that puts it all together:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
go func() {
// Your main program logic goes here
// For example, running a server
// ...
// Simulating a long-running operation
for {
select {
case <-interrupt:
// Perform necessary cleanup, graceful shutdown, etc.
// ...
// Exit the program
os.Exit(0)
default:
// Your main program logic continues here
fmt.Println("Doing some work...")
}
}
}()
<-interrupt
}
In this example, the program will keep printing "Doing some work..." until a signal (SIGINT or SIGTERM) is received. Then it will perform any necessary cleanup and exit the program.
Note that handling signals in a Go program does not guarantee immediate termination, especially if you have long-running operations or complex cleanup tasks. Therefore, it is important to design your program in a way that allows for graceful termination.