The function declaration is:
func Notify(c chan<- , sig ...)
Official description:
The Notify function allows the signal packet to forward the input signal to c. If the signal to be passed is not listed, all input signals are passed to c; otherwise only the listed input signals are passed.
The signal packet will not block in order to send information to C (that is, if C blocks when sending, the signal packet will be abandoned directly): the caller should ensure that C has enough cache space to keep up with the expected signal frequency. For channels that use a single signal for notification, a cache of 1 is sufficient.
Sample code:
ch := make(chan , 1) (ch, , , , , syscall.SIGUSR1) for { s := <-ch switch s { case : ("SIGSTOP") return case : ("SIGSTOP") return case : ("SIGHUP") return case : ("SIGKILL") return case syscall.SIGUSR1: ("SIGUSR1") return default: ("default") return } }
The above code tells signal to notify the corresponding signal, and then perform different processing for different signals in the for loop. The for loop is a dead loop.
Additional: About using a channel with cache
package main import ( "fmt" "os" "os/signal" ) func main() { // Set up channel on which to send signal notifications. // We must use a buffered channel or risk missing the signal // if we're not ready to receive when the signal is sent. c := make(chan , 1) (c, ) // Block until a signal is received. s := <-c ("Got signal:", s) }
The above code is the example code, and the comment says:
We have to use a buffered channel
Otherwise, when we are sending the signal, we are not ready to receive it, and there is a risk of losing the signal.
I haven't understood this comment yet, so I looked through the source code $GOROOT/src/os/signal/, there is such a piece of code, and the comment has "send but not blocking". This should be the reason why the signal is "possible to be lost".
... for c, h := range { if (n) { // send but do not block for it select { case c <- sig: default: } } } ...
So, I wrote a piece of code to test it:
package main import ( "log" "os" "os/signal" "time" ) func main() { c := make(chan ) (c, ) ( * 5) // Pretend to receive it in 5 seconds s := <-c (s) }
When using a channel without cache, no matter how many control + c is pressed during the 5-second sleep, the end of sleep will not be printed and the program will not be exited;
When using a cached channel, as long as a SIGINT is received, it will print and exit the program after sleep is completed.
This is what it does to use a cached channel.
The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.