Golang使用信号处理Unix命令
If you have no critics, you will likely have no success.
Accepting and processing signals from the operating system is important for various use cases in applications.
While many server-side languages have complicated or tedious approaches to processing signals from the OS, with Golang applications it’s extremely intuitive. Golang’s in-built OS package provides an easy way to integrate and react to Unix signals from your Go application. Let’s see how.
The Premise
Let’s say we want to build a Golang application that when requested to shutdown prints a message saying, “Thank you for using Golang.” Let’s set up the main function that basically keeps doing some work until an exit command is provided to the application.
1 | func main() { |
When you run this application and kill it by providing a kill signal from your OS (Ctrl + C
or Ctrl + Z
, in most cases), you may see an output similar to this one:
1 | Doing Work |
Now, we would like to interpret this kill signal within the Golang application and process it to print out the required exit message.
Receiving Signals
We will create a channel
to receive the command from the OS. The OS package provides the Signal
interface to handle signals and has OS-specific implementations.
1 | killSignal := make(chan os.Signal, 1) |
To notify killSignal
, we use the Notify
function provided by the signal
package. The first parameter takes a channel of a os.Signal
, while the next parameters accept a list of OS signals we want to notify our channel with.
1 | signal.Notify(killSignal, os.Interrupt) |
Alternatively, we can notify our signal with specific commands using the syscall package.
1 | signal.Notify(killSignal, syscall.SIGINT, syscall.SIGTERM) |
In order to process the signal, we’ll make our main
function block wait for the interrupt
signal using the killSignal
channel. On receiving a command from the OS, we’ll print the exit message and kill the application.
In order to process our work loop, let’s move that into a separate goroutine
using an anonymous function.
1 | go func() { |
While the work function runs in a separate routine, the main function will wait for the killSignal and print the exit message before exiting.
1 | <-killSignal |
The Code
With all the components put together, the final code is this:
1 | package main |
On running this, it keeps executing the work loop, and upon receiving an interrupt
signal from the OS, it prints the required message and then exits.
1 | Doing Work |
Conclusion
This simple example can be extrapolated to handle many real-life scenarios, such as gracefully shutting down servers and receiving commands in command-line applications.
https://betterprogramming.pub/using-signals-to-handle-unix-commands-in-golang-f09e9efb7769