Go by Example - IT: Segnali

Talvolta è necessario che i nostri programmi Go gesticano in modo corretto i segnali Unix Ad esempio, potremmo volere che il nostro programma termini in modo corretto se riceve un SIGTERM oppure vorremmo dire ad un programma a linea di comando di interrompersi se riceve un SIGINT. In questo esempio vedremo come è semplice gestire i segnali con i channel di Go.

package main
import "fmt"
import "os"
import "os/signal"
import "syscall"
func main() {

I segnali su Go vengono gestiti tramite l’invio di valori di tipo os.Signal su un channel. Qui creiamo un channel per ricevere queste notifiche, ed uno che utilizzeremo per la terminazione del programma.

    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)

La funzione signal.Notify registra questo channel per la ricezione di specifici segnali.

    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

Questa goroutine si blocca sul channel sigs in attesa di un segnale. Quando lo riceve, lo stamperà a schermo e aggiungerà un messaggio nel channel done, per notificare la goroutine main che può terminare.

    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
    }()

Il programma si bloccherà qui in attesa di un valore sul channel done e poi terminerà.

    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}

Quando eseguiamo questo programma si bloccherà in attesa di un segnale. Premendo ctrl-C (che il terminale mostrerà come ^C) inviamo un segnale di tipo SIGINT, causando la scrittura di interrupt e la successiva terminazione del programma.

$ go run signals.go
awaiting signal
^C
interrupt
exiting

Prossimo esempio: Exit.