Как SIGINT относится к другим сигналам завершения? - PullRequest
91 голосов
/ 28 октября 2010

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

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

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

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

Как 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?Если да, то какова причина этого и как будет отличаться обработка?

Ответы [ 6 ]

72 голосов
/ 29 октября 2010

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

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

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

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

9 голосов
/ 28 октября 2010

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

SA_KILL|SA_PROC,             /* SIGINT */
SA_KILL|SA_PROC,             /* SIGTERM */
7 голосов
/ 29 октября 2010

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

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

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

5 голосов

man 7 signal

Это удобная ненормативная справочная страница проекта man-страниц Linux , на которую вы часто хотите посмотреть информацию о сигналах Linux.

Версия 3.22 упоминает интересные вещи, такие как:

Сигналы SIGKILL и SIGSTOP не могут быть пойманы, заблокированы или проигнорированы.

и содержит таблицу:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process
SIGINT        2       Term    Interrupt from keyboard
SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal
SIGSEGV      11       Core    Invalid memory reference
SIGPIPE      13       Term    Broken pipe: write to pipe with no
                              readers
SIGALRM      14       Term    Timer signal from alarm(2)
SIGTERM      15       Term    Termination signal
SIGUSR1   30,10,16    Term    User-defined signal 1
SIGUSR2   31,12,17    Term    User-defined signal 2
SIGCHLD   20,17,18    Ign     Child stopped or terminated
SIGCONT   19,18,25    Cont    Continue if stopped
SIGSTOP   17,19,23    Stop    Stop process
SIGTSTP   18,20,24    Stop    Stop typed at tty
SIGTTIN   21,21,26    Stop    tty input for background process
SIGTTOU   22,22,27    Stop    tty output for background process

, который суммирует сигнал Action, который отличает, например, SIGQUIT от напр .: SIGINT от SIGQUIT, так как SIGQUIT имеет действие Core и SIGINT Term.

и действия документированы в одном документе:

The entries in the "Action" column of the tables below specify the default disposition for each signal, as follows:

Term   Default action is to terminate the process.

Ign    Default action is to ignore the signal.
Core   Default action is to terminate the process and dump core (see core(5)).
Stop   Default action is to stop the process.
Cont   Default action is to continue the process if it is currently stopped.

Некоторые сигналы соответствуют ANSI C, а другие нет

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

  • SIGINT и SIGTERM соответствуют стандарту ANSI C, поэтому более переносимы
  • SIGQUIT и SIGKILL не

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

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

, что делает SIGINT хорошим кандидатом на интерактивные Ctrl + C.

POSIX 7

POSIX 7 документирует сигналы с заголовком signal.h: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html

На этой странице также есть следующая интересная таблица, в которой упоминаются некоторые вещи, которые мы уже видели в man 7 signal:

Signal    Default Action   Description
SIGABRT   A                Process abort signal.
SIGALRM   T                Alarm clock.
SIGBUS    A                Access to an undefined portion of a memory object.
SIGCHLD   I                Child process terminated, stopped,
SIGCONT   C                Continue executing, if stopped.
SIGFPE    A                Erroneous arithmetic operation.
SIGHUP    T                Hangup.
SIGILL    A                Illegal instruction.
SIGINT    T                Terminal interrupt signal.
SIGKILL   T                Kill (cannot be caught or ignored).
SIGPIPE   T                Write on a pipe with no one to read it.
SIGQUIT   A                Terminal quit signal.
SIGSEGV   A                Invalid memory reference.
SIGSTOP   S                Stop executing (cannot be caught or ignored).
SIGTERM   T                Termination signal.
SIGTSTP   S                Terminal stop signal.
SIGTTIN   S                Background process attempting read.
SIGTTOU   S                Background process attempting write.
SIGUSR1   T                User-defined signal 1.
SIGUSR2   T                User-defined signal 2.
SIGTRAP   A                Trace/breakpoint trap.
SIGURG    I                High bandwidth data is available at a socket.
SIGXCPU   A                CPU time limit exceeded.
SIGXFSZ   A                File size limit exceeded.
3 голосов
/ 28 октября 2010

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

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

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

0 голосов
/ 28 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...