Введение
Лаборатория Сигналов демонстрирует, как обрабатывать Unix-сигналы в программах на Go с использованием каналов.
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
Лаборатория Сигналов демонстрирует, как обрабатывать Unix-сигналы в программах на Go с использованием каналов.
В некоторых случаях мы хотим, чтобы наши программы на Go умело обрабатывали Unix-сигналы. Например, мы можем захотеть, чтобы сервер прекращал работу gracefully, когда получает SIGTERM
, или чтобы командная строка прекращала обрабатывать ввод, если получает SIGINT
.
os.Signal
.signal.Notify
.## Когда мы запускаем эту программу, она будет заблокирована, ожидая сигнала.
## Нажав `ctrl-C` (что в терминале отображается как `^C`), мы можем отправить сигнал `SIGINT`,
## что вызовет вывод программы `interrupt` и затем выход.
$ go run signals.go
awaiting signal
^C
interrupt
exiting
Ниже представлен полный код:
// Иногда мы хотим, чтобы наша программа на Go умело обрабатывала
// [Unix-сигналы](https://en.wikipedia.org/wiki/Unix_signal).
// Например, мы можем захотеть, чтобы сервер прекращал работу gracefully,
// когда получает `SIGTERM`, или чтобы командная строка прекращала обрабатывать ввод,
// если получает `SIGINT`. Вот, как обрабатывать сигналы в Go с использованием каналов.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
// Работа с сигналами в Go осуществляется путем отправки значений `os.Signal`
// по каналу. Мы создадим канал для приема этих уведомлений. Обратите внимание,
// что этот канал должен быть буферизованным.
sigs := make(chan os.Signal, 1)
// `signal.Notify` регистрирует заданный канал для приема уведомлений
// о заданных сигналах.
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
// Мы могли бы получать из `sigs` здесь в основной функции,
// но давайте посмотрим, как это можно сделать в отдельной goroutine,
// чтобы продемонстрировать более реалистичную ситуацию graceful shutdown.
done := make(chan bool, 1)
go func() {
// Эта goroutine выполняет блокирующий прием сигналов.
// Когда она получает сигнал, она выводит его и затем уведомляет программу
// о том, что она может завершиться.
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
// Программа будет ждать здесь, пока не получит ожидаемый сигнал
// (как показано выше, когда goroutine отправляет значение по `done`),
// а затем выйдет.
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}
Лаборатория Сигналов демонстрирует, как обрабатывать Unix-сигналы в программах на Go с использованием каналов. Создав буферизованный канал для приема уведомлений о os.Signal
и зарегистрировав канал для приема уведомлений о заданных сигналах с использованием signal.Notify
, мы можем优雅но обрабатывать сигналы и выходить из программы, когда получаем ожидаемый сигнал.