В системах POSIX сигналы завершения обычно имеют следующий порядок (согласно многим страницам MAN и спецификации POSIX):
SIGTERM - вежливо попросить завершить процесс. Он должен завершиться корректно, очистив все ресурсы (файлы, сокеты, дочерние процессы и т. Д.), Удалив временные файлы и так далее.
SIGQUIT - более сильная просьба. Он должен прекратить некорректную очистку ресурсов, которые абсолютно нуждаются в очистке, но, возможно, не удалит временные файлы, возможно, где-нибудь запишет отладочную информацию; в некоторых системах также будет записан дамп ядра (независимо от того, пойман ли сигнал приложением или нет).
СИГКИЛЛ - сильнейшая просьба. Процесс даже не просит что-либо делать, но система очистит процесс, нравится ему это или нет. Скорее всего написан дамп ядра.
Как SIGINT вписывается в эту картину? Процесс CLI обычно завершается SIGINT, когда пользователь нажимает CRTL + C, однако фоновый процесс также может быть завершен SIGINT с помощью утилиты KILL. Что я не вижу в спецификациях или файлах заголовков, так это то, является ли SIGINT более или менее убедительным, чем SIGTERM, или есть ли вообще какая-либо разница между SIGINT и SIGTERM.
ОБНОВИТЬ:
Лучшее описание сигналов завершения, которое я нашел до сих пор, находится в документации GNU LibC . Это очень хорошо объясняет предполагаемое различие между SIGTERM и SIGQUIT.
О SIGTERM сказано:
Это нормальный способ вежливо попросить программу завершить работу.
А про SIGQUIT сказано:
[...] и производит дамп ядра при завершении процесса, как сигнал об ошибке программы. Вы можете думать об этом как о состоянии ошибки программы, «обнаруженной» пользователем. [...] Определенные виды очистки лучше не выполнять при обработке SIGQUIT. Например, если программа создает временные файлы, она должна обрабатывать другие запросы на завершение, удаляя временные файлы. Но SIGQUIT лучше не удалять их, чтобы пользователь мог изучить их вместе с дампом ядра.
И SIGHUP тоже достаточно хорошо объяснен. SIGHUP на самом деле не является сигналом завершения, это просто означает, что «соединение» с пользователем было потеряно, поэтому приложение не может ожидать, что пользователь прочитает какой-либо дальнейший вывод (например, вывод stdout / stderr), и нет ввода, ожидаемого от пользователь больше. Для большинства приложений это означает, что им лучше выйти. Теоретически приложение может также решить, что оно переходит в режим демона при получении SIGHUP и теперь работает как фоновый процесс, записывая выходные данные в настроенный файл журнала. Для большинства демонов, уже работающих в фоновом режиме, SIGHUP обычно означает, что они должны повторно проверить свои файлы конфигурации, поэтому вы отправляете его фоновым процессам после редактирования файлов конфигурации.
Однако на этой странице нет полезного объяснения SIGINT, кроме того, что он отправляется CRTL + C. Есть ли причина, по которой можно обрабатывать SIGINT иначе, чем SIGTERM? Если да, то по какой причине это было бы и чем было бы иначе?
sudo fuser -l
в командной строке. Для меня это вызывает:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
получить список сигналов.Ответы:
SIGTERM и SIGKILL предназначены для общих запросов «прекратить этот процесс». SIGTERM (по умолчанию) и SIGKILL (всегда) вызовут завершение процесса. SIGTERM может быть перехвачен процессом (например, чтобы он мог выполнить свою собственную очистку, если захочет) или даже полностью проигнорирован; но SIGKILL нельзя поймать или проигнорировать.
SIGINT и SIGQUIT предназначены специально для запросов от терминала: для генерации этих сигналов могут быть назначены определенные входные символы (в зависимости от настроек управления терминалом). Действие по умолчанию для SIGINT - это тот же вид завершения процесса, что и действие по умолчанию для SIGTERM и неизменное действие для SIGKILL; действием по умолчанию для SIGQUIT также является завершение процесса, но могут произойти дополнительные действия, определяемые реализацией, такие как создание дампа ядра. При необходимости процесс может либо поймать, либо проигнорировать.
SIGHUP, как вы говорите, предназначен для указания того, что терминальное соединение было потеряно, а не для того, чтобы быть сигналом завершения как таковым. Но, опять же, действие по умолчанию для SIGHUP (если процесс не улавливает или не игнорирует его) - завершить процесс таким же образом, как SIGTERM и т. Д.
В определениях POSIX есть таблица, в
signal.h
которой перечислены различные сигналы, их действия и цели по умолчанию, а в главе « Общий интерфейс терминала» содержится более подробная информация о сигналах, связанных с терминалом.источник
Как заметил DarkDust, многие сигналы имеют одинаковые результаты, но процессы могут присоединять к ним разные действия, различая, как генерируется каждый сигнал. Глядя на исходный код ядра FreeBSD (kern_sig.c), я вижу, что два сигнала обрабатываются одинаково, они завершают процесс и доставляются в любой поток.
источник
man 7 signal
Это удобная ненормативная справочная страница проекта man-страниц Linux, на которой вы часто хотите найти информацию о сигналах Linux.
Версия 3.22 упоминает такие интересные вещи, как:
и содержит таблицу:
который суммирует сигнал,
Action
который отличает, например, SIGQUIT от SIGQUIT, поскольку SIGQUIT имеет действиеCore
и SIGINTTerm
.Действия описаны в том же документе:
Я не вижу никакой разницы между SIGTERM и SIGINT с точки зрения ядра, поскольку оба имеют действие
Term
и оба могут быть пойманы. Похоже, что это просто «различие в общепринятых правилах использования»:kill
Некоторые сигналы соответствуют стандарту ANSI C, а другие нет.
Существенная разница в том, что:
Они описаны в разделе «7.14 Обработка сигналов» проекта C99 N1256 :
что делает SIGINT хорошим кандидатом для интерактивного Ctrl + C.
POSIX 7
POSIX 7 документирует сигналы с
signal.h
заголовком: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlНа этой странице также есть следующая интересная таблица, в которой упоминаются некоторые вещи, которые мы уже видели
man 7 signal
:BusyBox init
Команда BusyBox по умолчанию 1.29.2
reboot
отправляет SIGTERM процессам, засыпает на секунду, а затем отправляет SIGKILL. Кажется, это обычное соглашение для разных дистрибутивов.Когда вы завершаете работу системы BusyBox с помощью:
он отправляет сигнал процессу инициализации.
Затем обработчик сигнала инициализации вызывает:
который выводит на терминал:
Вот минимальный конкретный пример этого .
Сигналы, отправленные ядром
источник
После быстрого поиска в Google sigint vs sigterm , похоже, единственная предполагаемая разница между ними заключается в том, был ли он инициирован сочетанием клавиш или явным вызовом
kill
.В результате вы можете, например, перехватить sigint и сделать с ним что-то особенное, зная, что он, вероятно, был отправлен с помощью сочетания клавиш. Возможно, обновите экран или что-то в этом роде, вместо того, чтобы умирать (не рекомендуется, как люди ожидают
^C
убить программу, просто пример).Я также узнал, что
^\
должен отправлять sigquit, который я могу начать использовать сам. Выглядит очень полезно.источник
Используя
kill
(как системный вызов, так и утилиту), вы можете послать практически любой сигнал любому процессу, если у вас есть разрешение. Процесс не может различить, как сигнал появился и кто его послал.При этом SIGINT действительно предназначен для прерывания Ctrl-C, в то время как SIGTERM является общим терминальным сигналом. Не существует концепции «более сильного» сигнала, за единственным исключением, что есть сигналы, которые нельзя заблокировать или обработать (SIGKILL и SIGSTOP, согласно странице руководства).
Сигнал может быть «более сильным», чем другой сигнал, только в отношении того, как принимающий процесс обрабатывает сигнал (и каково действие по умолчанию для этого сигнала). Например, по умолчанию и SIGTERM, и SIGINT приводят к завершению. Но если вы проигнорируете SIGTERM, он не завершит ваш процесс, в то время как SIGINT все еще завершает работу.
источник
За исключением нескольких сигналов, обработчики сигналов могут улавливать различные сигналы, или поведение по умолчанию при получении сигнала может быть изменено. См. Подробности на
signal(7)
странице руководства .источник
SIGINT
(« программное прерывание ») отправляется, когда пользователь набирает символ INTR (обычноC-c
)». «SIGINT 2 Term Interrupt с клавиатуры». Вы нажимаете Ctrl-C,SIGINT
отправляется. Процесс нормально умирает. Что еще дать?