Segnali

Segnali #

// Talvolta è necessario che i nostri programmi Go
// gesticano in modo corretto i <a href="https://it.wikipedia.org/wiki/Segnale_(informatica)">segnali Unix</a>
// 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