Как SIGINT относится к другим сигналам завершения?

в системах POSIX сигналы завершения обычно имеют следующий порядок (согласно многим MAN-страницам и спецификации POSIX):

  1. SIGTERM-вежливо попросите процесс завершить. Он должен завершаться изящно, очищая все ресурсы (файлы, сокеты, дочерние процессы и т. д.), удаление временных файлов и так далее.

  2. SIGQUIT - более сильный запрос. Он должен прекратить ungraceful, все еще очищая ресурсы, которые абсолютно необходимы очистка, но, возможно, не удалять временные файлы, может быть, написать отладочную информацию где-нибудь; на какой-то системе также будет записан дамп ядра (независимо от того, пойман ли сигнал приложением или нет).

  3. SIGKILL-самый сильный запрос. Процесс даже не просят ничего делать, но система очистит процесс, нравится это или нет. Скорее всего, написан дамп ядра.

Как SIGINT вписывается в эту картину? Процессу CLI обычно завершается SIGINT, когда пользователь нажимает CRTL+C, однако фоновый процесс также может быть завершен SIGINT с помощью утилиты KILL. То, что я не вижу в спецификациях или заголовочных файлах, - это если SIGINT более или менее силен, чем SIGTERM, или если есть какая-либо разница между SIGINT и SIGTERM вообще.

обновление:

лучшее описание сигналов завершения, которые я нашел до сих пор, находится в документация GNU LibC. Это объясняет очень Ну, что есть предполагаемая разница между SIGTERM и SIGQUIT.

Он говорит о SIGTERM:

Это обычный способ вежливо попросить программу завершить работу.

и это говорит о SIGQUIT:

[...] и создает дамп ядра, когда он завершает процесс, как и сигнал ошибки программы. Вы можете думать об этом как об ошибке программы, "обнаруженной" пользователем. [...] Некоторые виды очистки лучше всего опустить при обработке SIGQUIT. Например, если программа создает временные файлы, он должен обрабатывать другие запросы завершения, удаляя временные файлы. Но для SIGQUIT лучше не удалять их, чтобы пользователь мог изучить их в в сочетании с отвалом ядра.

и вздох также объясняется достаточно хорошо. SIGHUP на самом деле не является сигналом завершения, это просто означает, что" соединение " с пользователем было потеряно, поэтому приложение не может ожидать пользователя чтобы прочитать любой дальнейший выход (например, выход stdout/stderr), и больше нет входа, чтобы ожидать от пользователя. Для большинства приложений, которые означают, что они лучше бросить. Теоретически приложение может также решить, что оно переходит в режим демона при получении SIGHUP и теперь работает как фоновый процесс, записывая выходные данные в настроенный файл журнала. Для большинства демонов, уже работающих в фоновом режиме, SIGHUP обычно означает, что они должны пересмотреть свои файлы конфигурации, поэтому вы отправляете их в фоновые процессы после редактирование конфигурационных файлов.

однако на этой странице нет полезного объяснения SIGINT, кроме того, что оно отправлено CRTL+C. Есть ли причина, по которой можно обрабатывать SIGINT по-другому, чем SIGTERM? Если да, то по какой причине это будет и как будет отличаться обработка?

6 ответов


SIGTERM и SIGKILL предназначены для запросов общего назначения "завершить этот процесс". SIGTERM (по умолчанию) и SIGKILL (всегда) вызовут завершение процесса. SIGTERM может быть пойман процессом (например, чтобы он мог сделать свою собственную очистку, если захочет) или даже полностью проигнорирован; но SIGKILL нельзя поймать или проигнорировать.

SIGINT и SIGQUIT предназначены специально для запросов от терминала: для их генерации могут быть назначены определенные входные символы сигналы (в зависимости от настройки терминала). Действие по умолчанию для SIGINT является тем же видом завершения процесса, что и действие по умолчанию для SIGTERM и неизменяемое действие для SIGKILL; действие по умолчанию для SIGQUIT также является завершением процесса, но могут возникнуть дополнительные действия, определенные реализацией, такие как создание дампа ядра. При необходимости процесс может быть пойман или проигнорирован.

SIGHUP, как вы говорите, предназначен для указания на то, что терминал соединение было потеряно, а не быть сигналом прекращения как таковым. Но, опять же, действие по умолчанию для SIGHUP (если процесс не улавливает или игнорирует его) заключается в том, чтобы завершить процесс так же, как SIGTERM и т. д. .

есть таблица в POSIX определения signal.h в котором перечислены различные сигналы и их действия и цели по умолчанию, а также Общий Интерфейс Терминала глава включает в себя гораздо более подробную информацию о сигналы, связанные с терминалом.


Как отметил DarkDust, многие сигналы имеют одинаковые результаты, но процессы могут присоединять к ним различные действия, различая, как генерируется каждый сигнал. Просмотр исходного кода ядра FreeBSD (kern_sig.c) я вижу, что два сигнала обрабатываются одинаково, они завершают процесс и доставляются в любой поток.

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */

после быстрого поиска Google для радиоразведки против команды SIGTERM, похоже, единственное предполагаемое различие между ними заключается в том, было ли оно инициировано сочетанием клавиш или явным вызовом kill.

в результате вы можете, например, перехватить sigint и сделать с ним что-то особенное, зная, что он, вероятно, был отправлен с помощью сочетания клавиш. Возможно, обновите экран или что-то еще, вместо того, чтобы умирать (не рекомендуется, как люди ожидают ^C убить программа, просто пример).

Я также узнал, что ^\ должен отправить sigquit, который я могу начать использовать сам. Выглядит очень полезным.


некоторые из них ANSI C, а другие нет

значительная разница в том, что:

  • SIGINT и SIGTERM являются ANSI C, таким образом, более портативными
  • SIGQUIT и SIGKILL не

они описаны в разделе "7.14 обработка сигналов"C99 проект N1256:

  • SIGINT получение интерактивного сигнала внимания
  • SIGTERM запрос на прекращение программа

Что делает SIGINT хорошим кандидатом для интерактивного Ctrl + C.


С помощью kill (как системный вызов, так и утилита " вы можете отправить почти любой сигнал на любой процесс, учитывая, что у вас есть разрешение. Процесс не может отличить, как сигнал ожил и кто его послал.

это, как говорится, SIGINT действительно предназначен для пения прерывания Ctrl-C, в то время как SIGTERM является общим терминальным сигналом. Нет понятия о том, что сигнал "более сильный", за исключением того, что есть сигналы, которые не могут быть заблокированы или обработаны (SIGKILL и sigstop, согласно Man-странице).

сигнал может быть только "более сильным", чем другой сигнал относительно того, как процесс приема обрабатывает сигнал (и какое действие по умолчанию для этого сигнала). Например, по умолчанию SIGTERM и SIGINT приводят к завершению. Но если вы игнорируете SIGTERM, он не завершит ваш процесс, в то время как SIGINT все еще делает это.


за исключением нескольких сигналов, обработчики сигналов могут уловить сигналы, или поведение по умолчанию при получении сигнала может быть изменен. Вижу signal(7) страница для деталей.