В каком порядке я должен посылать сигналы для постепенного завершения процессов? - PullRequest
77 голосов
/ 27 марта 2009

В комментарии на этот ответ другого вопроса , комментатор говорит:

не используйте kill -9, если абсолютно необходимо! SIGKILL не может быть пойман в ловушку так убитая программа не может запустить процедуры выключения, например, стирать временные файлы. Сначала попробуйте HUP (1), затем INT (2), затем QUIT (3)

Я согласен в принципе с SIGKILL, но остальное для меня новость. Учитывая, что сигнал по умолчанию, отправляемый kill, равен SIGTERM, я ожидаю, что это наиболее ожидаемый сигнал для постепенного отключения произвольного процесса. Кроме того, я видел, как SIGHUP использовался по причинам, не связанным с завершением, например, говоря демону «перечитайте ваш файл конфигурации». И мне кажется, что SIGINT (то же самое прерывание, которое вы обычно получаете с помощью Ctrl-C, верно?) Не так широко поддерживается, как должно быть, или завершается довольно неблагодарно.

Учитывая, что SIGKILL является последним средством & mdash; Какие сигналы и в каком порядке следует отправлять в произвольный процесс, чтобы отключить его как можно более изящно?

Пожалуйста, подкрепите свои ответы подтверждающими фактами (помимо личных предпочтений или мнений) или ссылками, если можете.

Примечание: меня особенно интересуют лучшие практики, включающие рассмотрение bash / Cygwin.

Редактировать: Пока что никто не упоминает INT или QUIT, и есть ограниченное упоминание HUP. Есть ли какая-либо причина включать их в упорядоченный процесс убийства?

Ответы [ 7 ]

98 голосов
/ 27 марта 2009

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

Некоторые люди считают, что разумный стандартный способ завершить процесс - отправить ему множество сигналов, таких как HUP, INT, TERM и, наконец, KILL. Это нелепо. Правильный сигнал для завершения - это SIGTERM, и если SIGTERM не завершает процесс мгновенно, как вы могли бы предпочесть, то это потому, что приложение выбрало обработку сигнала. Это означает, что у него есть очень веская причина не прекращать работу немедленно: он должен выполнить работу по очистке. Если вы прервете эту очистку работой с другими сигналами, вы не узнаете, какие данные из памяти еще не сохранены на диске, какие клиентские приложения остались зависшими или прерываете ли вы их «в середине предложения», что фактически является повреждением данных.

Дополнительную информацию о реальном значении сигналов см. В sigaction (2). Не путайте «Действие по умолчанию» с «Описанием», это не одно и то же.

SIGINT используется для сигнализации интерактивного «прерывания клавиатуры» процесса. Некоторые программы могут обрабатывать ситуацию особым образом для пользователей терминалов.

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

SIGKILL используется для принудительного удаления процесса из ядра. Он особенный в том смысле, что фактически он не является сигналом для процесса, а интерпретируется ядром напрямую.

Не отправлять SIGKILL. SIGKILL, безусловно, никогда не должен отправляться сценариями. Если приложение обрабатывает SIGTERM, очистка может занять секунду, может занять минуту, может занять час . В зависимости от того, что приложение должно быть сделано, прежде чем оно будет готово к концу. Любая логика, что « предполагает », последовательность очистки приложения занимала достаточно много времени, и ее нужно было быстро или быстро активировать через X секунд, это просто неправильно .

Единственная причина, по которой приложению понадобится SIGKILL для завершения, - это если что-то вышло из строя во время последовательности очистки. В этом случае вы можете открыть терминал и SIGKILL его вручную. Кроме того, единственная причина, по которой вы что-то делаете SIGKILL, заключается в том, что вы ХОТИТЕ , чтобы предотвратить его очистку.

Несмотря на то, что полмира слепо посылает SIGKILL через 5 секунд, это все равно ужасно неправильно.

11 голосов
/ 08 июня 2016

Короткий ответ : Отправить SIGTERM, 30 секунд спустя, SIGKILL. То есть отправьте SIGTERM, подождите немного (это может варьироваться от программы к программе, вы можете лучше знать свою систему, но достаточно 5–30 секунд. При выключении машины вы можете увидеть, что она автоматически ожидает до 1 30-х годов. Почему спешка, в конце концов?), А затем отправить SIGKILL.

Разумный ответ : SIGTERM, SIGINT, SIGKILL Этого более чем достаточно. Процесс очень , вероятно, прекратится до SIGKILL.

Длинный ответ : SIGTERM, SIGINT, SIGQUIT, SIGABRT, SIGKILL

В этом нет необходимости, но, по крайней мере, вы не вводите в заблуждение процесс, касающийся вашего сообщения. Все эти сигналы do означают, что вы хотите, чтобы процесс остановил свою работу и завершил работу.

Независимо от того, какой ответ вы выберете из этого объяснения, имейте это в виду!

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

Итак, вы должны думать как программист. Вы бы закодировали обработчик функции, скажем, для SIGHUP, чтобы выйти из программы, которая соединяется с чем-то, или вы зациклились бы, чтобы попытаться соединиться снова? Это главный вопрос здесь! Вот почему важно просто отправлять сигналы, которые означают, что вы намерены.

Почти глупый длинный ответ :

Таблица ниже содержит соответствующие сигналы и действия по умолчанию, если программа не обрабатывает их.

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

Сигналы со звездочкой (*) рекомендуются НЕ . Важно то, что вы никогда не узнаете, для чего это запрограммировано. Специально SIGUSR! Это может запустить апокалипсис (это бесплатный сигнал для программиста делать все, что он / она хочет!). Но, если не обработано ИЛИ , в маловероятном случае, когда оно обрабатывается для завершения, программа завершит работу.

В таблице сигналы с параметрами по умолчанию для завершения и создания дампа ядра остаются в конце, непосредственно перед SIGKILL.

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGTERM      15       Term    Termination signal
SIGINT        2       Term    Famous CONTROL+C interrupt from keyboard
SIGHUP        1       Term    Disconnected terminal or parent died
SIGPIPE      13       Term    Broken pipe
SIGALRM(*)   14       Term    Timer signal from alarm
SIGUSR2(*)   12       Term    User-defined signal 2
SIGUSR1(*)   10       Term    User-defined signal 1
SIGQUIT       3       Core    CONTRL+\ or quit from keyboard
SIGABRT       6       Core    Abort signal from abort(3)
SIGSEGV      11       Core    Invalid memory reference
SIGILL        4       Core    Illegal Instruction
SIGFPE        8       Core    Floating point exception
SIGKILL       9       Term    Kill signal

Тогда я бы предложил для этого почти глупый длинный ответ : SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGQUIT, SIGABRT, SIGKILL

И, наконец,

Определенно глупый длинный длинный ответ :

Не пытайтесь делать это дома.

SIGTERM, SIGINT, SIGHUP, SIGPIPE, SIGALRM, SIGUSR2, SIGUSR1, SIGQUIT, SIGABRT, SIGSEGV, SIGILL, SIGFPE и если ничего не получится, SIGKILL.

SIGUSR2 следует попробовать до SIGUSR1, потому что нам лучше, если программа не обработает сигнал. И гораздо более вероятно, что он обработает SIGUSR1, если он обработает только один из них.

Кстати, УБИЙСТВО : отправка SIGKILL в процесс, как указано в другом ответе, не является ошибкой. Хорошо, подумайте, что происходит, когда вы отправляете команду shutdown? Он будет пытаться только SIGTERM и SIGKILL. Почему вы думаете, что это так? И зачем вам другие сигналы, если в самой команде shutdown используются только эти два?


Теперь вернемся к длинному ответу , это хороший переводчик:

for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done

Он спит в течение 30 секунд между сигналами. Зачем еще вам нужен oneliner ? ;)

Также рекомендуется: попробуйте только с сигналами 15 2 9 из разумного ответа .

безопасность : уберите второе echo, когда будете готовы к работе. Я называю это dry-run для лайнеров . Всегда используйте его для проверки.


Сценарий убито грациозно

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

Ссылка GitHub на Хранилище Killgracefully

7 голосов
/ 27 марта 2009

Обычно вы отправляете SIGTERM, по умолчанию для kill. По умолчанию это причина. Только если программа не завершает работу в разумные сроки, вы должны прибегнуть к SIGKILL. Но обратите внимание, что с SIGKILL программа не имеет возможности убирать вещи и данные могут быть повреждены.

Что касается SIGHUP, HUP означает «зависание» и исторически означало, что модем отключен. По сути, это эквивалентно SIGTERM. Причина, по которой демоны иногда используют SIGHUP для перезапуска или перезагрузки конфигурации, заключается в том, что демоны отсоединяются от любых управляющих терминалов, поскольку демон не нуждается в них и поэтому никогда не получит SIGHUP, так что сигнал считается "освобожденным" для общего пользования. Не все демоны используют это для перезагрузки! Действие по умолчанию для SIGHUP - завершить, и многие демоны ведут себя таким образом! Так что вы не можете слепо посылать SIGHUP s демонам и ожидать, что они выживут.

Редактировать: SIGINT, вероятно, неуместно завершать процесс, так как он обычно привязан к ^C или к любой другой настройке терминала для прерывания программы. Многие программы фиксируют это для своих собственных целей, поэтому достаточно часто, чтобы это не работало. SIGQUIT обычно по умолчанию создает дамп ядра, и если вы не хотите, чтобы файлы ядра лежали вокруг, это также не является хорошим кандидатом.

Итог: если вы отправите SIGTERM, и программа не умрет в течение вашего периода времени, отправьте ее SIGKILL.

6 голосов
/ 27 марта 2009

SIGTERM фактически означает отправку заявления с сообщением: « будь так добр и покончишь с собой ». Он может быть перехвачен и обработан приложением для запуска кода очистки и завершения работы.

SIGKILL не может быть отслежено приложением. Приложение убито ОС без каких-либо шансов на очистку.

Обычно отправляют SIGTERM сначала, поспят некоторое время, затем отправляют SIGKILL.

4 голосов
/ 27 марта 2009
  • SIGTERM эквивалентно «нажатию на« X »» в окне.
  • SIGTERM - это то, что Linux использует первым, когда он выключается.
2 голосов
/ 26 января 2017

При всех обсуждениях здесь не было предложено никакого кода. Вот мой дубль:

#!/bin/bash

$pid = 1234

echo "Killing process $pid..."
kill $pid

waitAttempts=30 
for i in $(seq 1 $waitAttempts)
do
    echo "Checking if process is alive (attempt #$i / $waitAttempts)..."
    sleep 1

    if ps -p $pid > /dev/null
    then
        echo "Process $pid is still running"
    else
        echo "Process $pid has shut down successfully"
        break
    fi
done

if ps -p $pid > /dev/null
then
    echo "Could not shut down process $pid gracefully - killing it forcibly..."
    kill -SIGKILL $pid
fi
0 голосов
/ 27 марта 2009

HUP звучит для меня как мусор. Я отправил бы его, чтобы демон пересмотрел его конфигурацию.

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

Подробнее об этом на Википедии

...