Tratando sinais com Go
Tratar sinais é uma boa prática. Dessa forma, você pode finalizar seu programa graciosamente, liberando recursos e fechando bancos de dados, em vez de simplesmente encerrar o programa. Tratar sinais do sistema operacional com Golang é simples, pois o sistema envia o sinal para um canal. Basta escutar esse canal.
Primeiro, criamos um canal:
sc := make(chan os.Signal, 1)
Em seguida, informamos o tipo de sinal que nos interessa. No caso, ^C, ou seja, SIGINT.
signal.Notify(sc, os.Interrupt)
Você pode informar mais de um sinal. Basta adicionar mais argumentos, por exemplo: signal.Notify(sc, os.Interrupt, syscall.SIGTERM)
.
Os sinais que considero mais interessantes de tratar são:
os.Interrupt
: igual asyscall.SIGINT
, representa o sinal ^Csyscall.SIGTERM
: sinal de terminação, geralmente enviado pelo comandokill
syscall.SIGWINCH
: sinal de redimensionamento de janela (quando o terminal é redimensionado)syscall.SIGUSR1
: sinal de usuário 1 (você pode criar seus próprios sinais)syscall.SIGUSR2
: sinal de usuário 2
Então, basta aguardar o canal receber um sinal.
<-sc
Você precisa tratar os sinais em uma goroutine.
Exemplo
go func() {
sc := make(chan os.Signal, 1)
signal.Notify(
sc,
os.Interrupt,
syscall.SIGTERM,
syscall.SIGWINCH,
syscall.SIGUSR1,
syscall.SIGUSR2)
for {
s := <-sc
switch s {
case os.Interrupt:
fmt.Printf("\r\nVocê pressionou ^C\r\n")
os.Exit(0)
case syscall.SIGTERM:
fmt.Printf("\r\nVocê enviou SIGTERM\r\n")
os.Exit(0)
case syscall.SIGUSR1:
fmt.Printf("\r\nVocê enviou SIGUSR1\r\n")
case syscall.SIGUSR2:
fmt.Printf("\r\nVocê enviou SIGUSR2\r\n")
case syscall.SIGWINCH:
fmt.Printf("\r\nA janela foi redimensionada\r\n")
}
}
}()
c := make(chan struct{})
<-c
Os sinais SIGUSR1
e SIGUSR2
são sinais de usuário. Você pode criar seus próprios sinais para, por exemplo, solicitar informações ou alterar o comportamento do programa.
Para enviar sinais de usuário, use o comando kill
com a opção -USR1
ou -USR2
.
kill -USR1 <pid>
O sinal SIGWINCH
é enviado quando a janela do terminal é redimensionada. Você pode usá-lo para capturar as novas dimensões e redimensionar a janela do seu programa.
Os sinais SIGTERM
e SIGINT
são sinais de terminação. O primeiro é enviado pelo comando kill
, e o segundo é enviado quando o usuário pressiona ^C. Você pode usá-los para finalizar o programa graciosamente, fechando conexões e liberando recursos.
Vídeo com a explicação: