Make Ctrl+C cancel the context.Context
Ctrl+C famously terminates a program. By default in Go any running code is immediately stopped. But sometimes, you want to do a bit of clean-up before the program ends and this is especially elegant if you use the
Ctrl+C actually causes a signal to be sent to your program; the
SIGINT signal to be precise — referred to in Go as
The following code illustrates how to do this:
First, we create a global context with
context.Background before using
context.WithCancel to get a cancellation function: we can call this function to cancel the operations of the program.
Next, we trap the
SIGINT signal so we can run some code in response to it. The
signal.Notify function asks that any of the specified signals (in our case just
os.Interrupt) be sent down the channel
c rather then just immediately terminating the program.
We then defer a clean-up function that will run when the function is finished; it stops receiving the signals (via
signal.Stop) and calls the
cancel function to cancel the context.
In a separate goroutine (notice
go func()) we then use
select to wait for either a signal on the
c channel, or for the context itself to finish. Execution will block here waiting for one of those two things to happen before continuing. If we receive a signal on the
c channel, then we cancel the context by calling the
cancel function. In the case that the context cancels for other reasons (like a timeout, or whatever) this goroutine is cleaned up as the
<-ctx.Done(): case will hit and return.
Multiple calls to
cancel are ok, after the first one they’re just no-ops.
Check out Francesc Campoy’s video about how to use context: