Segnali
Un segnale è una notifica semantica dal sistema operativo, o generata dal sistema
stesso o generata da un altro processo Linux, oppure anche inviata dall'utente tramite il terminale di controllo.
Per esempio Ctrl-C invia il segnale SIGINT (interruzione) al processo in foreground.
Vi sono approssimativamente 35 segnali diversi in Linux.
I segnali si possono gestire col package os/signal
.
(640signals.go):
package main
import ("fmt"; "os"; "os/signal"; "syscall")
func main() {
// Channel che riceve le notifiche di segnali
sigs := make(chan os.Signal, 1)
// Channel che riceve notifica di uscita
done := make(chan bool, 1)
// Registrazione dei segnal accettati sul channel
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
// Goroutine che si blocca in attesa di un segnale.
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
// Indica al main che può uscire
done <- true
}()
// Main: attesa di segnale ed uscita
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
I segnali vengono ricevuti su un channel apposito.
Tranne il segnale SIGKILL, tutti gli altri segnali si possono ignorare o gestire. Un segnale non esplicitamente ignorato o gestito ha un comportamento di default, che di solito è la terminazione del processo.
La funzione Notify
indica quali segnali sono accettati e gestiti. La funzione Ignore
indicherebbe quali segnali sono ignorati.
La ricezione di un segnale non ignorato e non gestito, causa in Go una terminazione immediata con stack trace e dump dello stato dei registri di CPU.
E' buona norma gestire sempre il segnale SIGTERM, che è una richiesta educata di terminazione e da l'opportunità al programma di chiudere ogni risorsa e salvare il suo stato se lo desidera.