Я хочу захватить сигнал Ctrl+C( SIGINT
), отправленный с консоли, и распечатать некоторые частичные итоги прогона.
Возможно ли это на Голанге?
Примечание: Когда я впервые опубликовал вопрос, я был озадачен тем, Ctrl+Cчто SIGTERM
вместо того, чтобы быть SIGINT
.
for sig := range g {
вы также можете использовать,<-sigchan
как и в предыдущем ответе: stackoverflow.com/questions/8403862/…go run
консоль и отправляете SIGTERM через ^ C, сигнал записывается в канал, и программа отвечает, но, похоже, неожиданно выпадает из цикла. Это потому, что СИГРЕРМ тоже идетgo run
! (Это вызвало у меня существенное замешательство!)runtime.Gosched
в соответствующем месте (в главном цикле вашей программы, если он есть)Это работает:
источник
Чтобы немного добавить к другим ответам, если вы действительно хотите перехватить SIGTERM (сигнал по умолчанию, посылаемый командой kill), вы можете использовать
syscall.SIGTERM
вместо os.Interrupt. Помните, что интерфейс системного вызова зависит от системы и может работать не везде (например, в Windows). Но это хорошо работает, чтобы поймать оба:источник
signal.Notify
Функция позволяет указать несколько сигналов одновременно. Таким образом, вы можете упростить свой код доsignal.Notify(c, os.Interrupt, syscall.SIGTERM)
.os.Kill
соответствует кsyscall.Kill
, который является сигналом , который может быть послан , но не пойман. Это эквивалентно командеkill -9 <pid>
. Если вы хотите, чтобы ловитьkill <pid>
и изящно выключить, вы должны использоватьsyscall.SIGTERM
.Были (на момент публикации) один или два небольших опечаток в принятом ответе выше, так что вот исправленная версия. В этом примере я останавливаю профилировщик процессора при получении Ctrl+ C.
источник
runtime.Gosched
в соответствующем месте (в главном цикле вашей программы, если он есть)Кажется, что все вышеперечисленное работает, когда встроено , но страница сигналов gobyexample содержит действительно чистый и полный пример захвата сигналов. Стоит добавить в этот список.
источник
Death - это простая библиотека, которая использует каналы и группу ожидания для ожидания сигналов выключения. Как только сигнал будет получен, он вызовет метод close для всех ваших структур, которые вы хотите очистить.
источник
У вас может быть другая процедура, которая обнаруживает сигналы syscall.SIGINT и syscall.SIGTERM и передает их на канал с помощью signal.Notify . Вы можете отправить ловушку в эту программу с помощью канала и сохранить ее в срезе функции. Когда сигнал отключения обнаружен на канале, вы можете выполнить эти функции в срезе. Это можно использовать для очистки ресурсов, ожидания завершения выполнения процедур, сохранения данных или печати частичных итогов выполнения.
Я написал небольшую и простую утилиту для добавления и запуска хуков при выключении. Надеюсь, что это может помочь.
https://github.com/ankit-arora/go-utils/blob/master/go-shutdown-hook/shutdown-hook.go
Вы можете сделать это «отложенным» способом.
пример для корректного завершения работы сервера:
источник
Это еще одна версия, которая работает, если у вас есть задачи для очистки. Код оставит процесс очистки в их методе.
в случае, если вам нужно очистить основную функцию, вам нужно перехватить сигнал в основном потоке, используя go func ().
источник
Просто для записи, если кому-то нужен способ обработки сигналов в Windows. У меня было требование обрабатывать из prog A вызывающий prog B через os / exec, но prog B никогда не мог завершиться изящно, поскольку отправлял сигналы через ex. cmd.Process.Signal (syscall.SIGTERM) или другие сигналы не поддерживаются в Windows. Я справился с этим, создав временный файл в качестве сигнала ex. .signal.term через prog A и prog B необходимо проверить, существует ли этот файл на основе интервала, если файл существует, он выйдет из программы и при необходимости выполнит очистку, я уверен, что есть и другие способы, но это помогло.
источник