Signals
#
// Por vezes, é necessário que programas em Go tratem
// [sinais Unix](https://en.wikipedia.org/wiki/Unix_signal).
// Por exemplo, pode-se querer que um servidor seja desligado
// graciosamente ao receber um sinal `SIGTERM`, ou que uma
// ferramenta de linha de comando pare de processar um input
// ao receber um sinal `SIGINT`.
// Aqui está como tratar estes sinais com canais em Go.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// A notificação de sinais em Go, funciona enviando valores
// do tipo `os.Signal` em um canal. Aqui é criado um canal
// para receber estas notificações. Note que este canal deve
// ser `buffered`.
sigs := make(chan os.Signal, 1)
// `signal.Notify` registra determinado canal para
// receber notoficações de sinais específicos.
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
// O sinal poderia ser recebido pelo `sigs` aqui
// na função main, mas será feito em uma goroutine
// separada, para demonstrar como pode ser feito o
// desligamento gracioso de maneira mais realista.
done := make(chan bool, 1)
go func() {
// Esta goroutine executa um recebimento bloqueante
// de sinais. Ao receber um, o sinal será impresso
// e então o programa será notificado que pode ser
// finalizado.
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
// O código irá aguardar aqui até que seja recebido
// o sinal esperado (como indicado pela goroutine
// acima, que enviará um valor no canal `done`) e
// então finalizar.
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
# Ao executar este código, ficará bloqueado aguardando
# um sinal. Ao digitar `ctrl-C` (que o terminal exibe
# como `^C`) é enviado um sinal `SIGINT`, que dispara
# a impressão da palavra `interrupt` e a
# interrupção do programa.
$ go run signals.go
awaiting signal
^C
interrupt
exiting