In this article, we will introduce to you why signal.Notify
should use buffered channel. When we want to do graceful shutdown, we will use this function to shut down the service or connection normally. Through signal, we can detect the source of the signal and do the follow-up work (shut down DB connection, check if the job is finished … etc.).
|
|
The above example clearly shows that if you don’t use a buffered channel, you run a certain risk of not catching the Signal. So why is there this description? Let’s take a look with other examples.
Use unbuffered channel
Change the code to the following:
Run the above code and press ctrl + c, you will see Got signal: interrupt
, then we have some very complicated work to do before accepting channle, use time.Sleep
to test it first.
You will find that during the five seconds, no matter how you press ctrl + c, the program will not stop, and after five seconds, the program will not stop. You need to press ctrl + c again, and then the program will stop. What we expect is that if you press ctrl + c any time during the first five seconds, theoretically you will receive the first signal normally after five seconds. Let’s see why.
Reasons for formation
We open Golang’s singal.go
file, find the process
func, and you can see part of the code:
As you can see in the above code, if you use the unbuffered channel, any signal received within 5 seconds will run into the default condition, so the channel will not receive any value, which is why any action within 5 seconds will not be received at all after 5 seconds. To avoid this, we usually set the signal channel to buffer 1
to avoid interrupting the program to make sure the main program can receive a signal.