В комментарии к этому ответу на другой вопрос комментатор говорит:
не используйте kill -9 без крайней необходимости! SIGKILL не может быть перехвачен, поэтому убитая программа не может запускать какие-либо процедуры завершения работы, например, для удаления временных файлов. Сначала попробуйте HUP (1), затем INT (2), затем QUIT (3)
Я в принципе согласен SIGKILL
, но остальное для меня новость. Учитывая, что отправленный по умолчанию сигнал - kill
это SIGTERM
, я ожидал, что это наиболее часто ожидаемый сигнал для постепенного завершения произвольного процесса. Кроме того, я видел, как он SIGHUP
используется для непрекращающихся причин, таких как указание демону «перечитать ваш файл конфигурации». И мне кажется, что SIGINT
(то же самое прерывание, которое вы обычно получаете с помощью Ctrl-C, верно?) Не так широко поддерживается, как должно быть, или завершается довольно некрасиво.
Учитывая, что SIGKILL
это последнее средство - какие сигналы и в каком порядке следует отправлять произвольному процессу, чтобы завершить его как можно более изящно?
Пожалуйста, подкрепите свои ответы подтверждающими фактами (помимо личных предпочтений или мнений) или ссылками, если можете.
Примечание: меня особенно интересуют передовые методы, которые включают рассмотрение bash / Cygwin.
Изменить: до сих пор никто не упоминает INT или QUIT, и есть ограниченное упоминание о HUP. Есть ли причина включать их в упорядоченное уничтожение процессов?
источник
Ответы:
SIGTERM сообщает приложению о завершении. Другие сигналы сообщают приложению другие вещи, не связанные с завершением работы, но иногда могут иметь тот же результат. Не используйте их. Если вы хотите, чтобы приложение закрылось, сообщите ему об этом. Не подавайте ему вводящих в заблуждение сигналов.
Некоторые люди считают, что стандартный умный способ завершить процесс - это послать ему множество сигналов, таких как HUP, INT, TERM и, наконец, KILL. Это смешно. Правильный сигнал для завершения - это SIGTERM, и если SIGTERM не завершает процесс немедленно, как вы могли бы предпочесть, это потому, что приложение выбрало обработку сигнала. Это означает, что у него есть очень веская причина не прекращать работу немедленно: у него есть работа по очистке. Если вы прервете эту работу по очистке с помощью других сигналов, невозможно будет сказать, какие данные из памяти еще не сохранены на диск, какие клиентские приложения остались зависшими или прерываете ли вы его «на полпути», что фактически является повреждением данных.
Для получения дополнительной информации о реальном значении сигналов см. Sigaction (2). Не путайте «Действие по умолчанию» с «Описание», это не одно и то же.
SIGINT используется для сигнализации интерактивного «прерывания клавиатуры» процесса. Некоторые программы могут обрабатывать ситуацию особым образом для пользователей терминала.
SIGHUP используется, чтобы сигнализировать, что терминал исчез и больше не наблюдает за процессом. Это все. Некоторые процессы выбирают завершение работы в ответ, как правило, потому что их работа не имеет смысла без терминала, некоторые предпочитают выполнять другие действия, например перепроверять файлы конфигурации.
SIGKILL используется для принудительного удаления процесса из ядра. Он особенный в том смысле, что на самом деле это не сигнал процессу, а, скорее, интерпретируется ядром напрямую.
Не отправляйте SIGKILL. SIGKILL ни в коем случае не следует отправлять скриптами. Если приложение обрабатывает SIGTERM, его очистка может занять секунду, это может занять минуту, это может занять час . В зависимости от того, что нужно сделать приложению, прежде чем оно будет готово к завершению. Любая логика, которая « предполагает », что последовательность очистки приложения заняла достаточно много времени и требует быстрого вызова или SIGKILL через X секунд, просто неверна .
Единственная причина, по которой приложению может потребоваться SIGKILL для завершения, - это если что-то выйдет из строя во время его последовательности очистки. В этом случае вы можете открыть терминал и SIGKILL вручную. Помимо этого, единственная другая причина, по которой вы должны SIGKILL что-то, - это то, что вы ХОТИТЕ предотвратить самоочищение.
Несмотря на то, что половина мира слепо посылает SIGKILL через 5 секунд, это все равно ужасно неправильно.
источник
Короткий ответ : Отправить
SIGTERM
, через 30 секунд,SIGKILL
. То есть отправьтеSIGTERM
, подождите немного (это может отличаться от программы к программе, вы можете лучше знать свою систему, но достаточно от 5 до 30 секунд. При выключении машины вы можете увидеть, что она автоматически ждет до 1:30 секунд. Зачем все-таки спешить?), То пошлитеSIGKILL
.Разумный ответ :
SIGTERM
,SIGINT
,SIGKILL
Это больше , чем достаточно. Весьма вероятно, что процесс завершится раньшеSIGKILL
.Длинный ответ :
SIGTERM
,SIGINT
,SIGQUIT
,SIGABRT
,SIGKILL
В этом нет необходимости, но, по крайней мере, вы не вводите в заблуждение процесс, касающийся вашего сообщения. Все эти сигналы действительно означает , что вы хотите , чтобы процесс остановить то , что он делает и выход.
Неважно, какой ответ вы выберете из этого объяснения, имейте это в виду!
Если вы отправляете сигнал, который означает что-то еще, процесс может обработать его по-разному (с одной стороны). С другой стороны, если процесс не обрабатывает сигнал, в конце концов, не имеет значения, что вы отправляете, процесс все равно завершится (когда действие по умолчанию, конечно, завершается).
Итак, вы должны думать как программист. Вы бы закодировали обработчик функции, скажем,
SIGHUP
для выхода из программы, которая к чему-то подключается, или вы бы зациклили ее, чтобы попытаться подключиться снова? Это главный вопрос! Вот почему важно просто посылать сигналы, которые означают то, что вы намереваетесь.Почти глупый длинный ответ :
В таблице ниже содержатся соответствующие сигналы и действия по умолчанию в случае, если программа их не обрабатывает.
Я заказал их в том порядке, который я предлагаю использовать (кстати, я предлагаю вам использовать разумный ответ , а не этот здесь), если вам действительно нужно попробовать их все (было бы забавно сказать, что таблица упорядочена с точки зрения разрушения, которые они могут вызвать, но это не совсем так).
Сигналы со звездочкой (*) НЕ рекомендуются. В них важно то, что вы никогда не узнаете, на что они запрограммированы. Специально
SIGUSR
! Он может запустить апокалипс (это бесплатный сигнал для программиста делать все, что он хочет!). Но, если она не обрабатывается ИЛИ, в маловероятном случае, она завершается, программа завершается.В таблице сигналы с параметрами по умолчанию для завершения и генерации дампа ядра оставлены в конце, непосредственно перед
SIGKILL
.Тогда я предложил бы для этого почти глупого длинного ответа :
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 секунд. Зачем еще вам нужен одинарный лайнер ? ;)
Также рекомендуется: попробуйте только сигналы
15 2 9
из разумного ответа .безопасность : снимите второй,
echo
когда будете готовы к работе. Я называю это моимdry-run
для онлайн-пользователей . Всегда используйте его для тестирования.Скрипт killgracefully
На самом деле меня настолько заинтриговал этот вопрос, что я решил создать небольшой скрипт для этого. Пожалуйста, не стесняйтесь скачать (клонировать) его здесь:
Ссылка GitHub на репозиторий Killgracefully
источник
Обычно вы отправляете
SIGTERM
, по умолчанию kill. Это значение по умолчанию. Вам следует прибегать только в том случае, если программа не завершает работу в течение разумного периода времениSIGKILL
. Но учтите, что сSIGKILL
программой нет возможности очистить вещи и данные могут быть повреждены.Что касается
SIGHUP
,HUP
означает «повесить трубку» и исторически означало, что модем отключился. По сути, это эквивалентSIGTERM
. Причина, по которой демоны иногда используютSIGHUP
для перезапуска или перезагрузки конфигурации, заключается в том, что демоны отсоединяются от любых управляющих терминалов, так как демон не нуждается в них и, следовательно, никогда не получит ихSIGHUP
, поэтому этот сигнал считался «освобожденным» для общего использования. Не все демоны используют это для перезагрузки! Действие по умолчанию для SIGHUP - завершить работу, и многие демоны так себя ведут! Поэтому вы не можете слепо посылатьSIGHUP
s демонам и ожидать, что они выживут.Изменить:
SIGINT
вероятно, нецелесообразно завершать процесс, поскольку он обычно привязан к^C
настройке терминала для прерывания программы. Многие программы фиксируют это для своих целей, так что это достаточно часто, чтобы это не работало.SIGQUIT
обычно по умолчанию создается дамп ядра, и, если вы не хотите, чтобы вокруг него лежали файлы ядра, это тоже не лучший кандидат.Резюме: если вы отправляете,
SIGTERM
а программа не умирает в установленные сроки, отправьте ееSIGKILL
.источник
SIGTERM
на самом деле означает отправку приложению сообщения: « будьте так добры и покончите жизнь самоубийством ». Он может быть перехвачен и обработан приложением для запуска кода очистки и завершения работы.SIGKILL
не может быть захвачен приложением. Приложение убивает ОС без всякого шанса на очистку.Обычно
SIGTERM
сначала отправить , поспать, потом отправитьSIGKILL
.источник
источник
Несмотря на все происходящее здесь обсуждение, никакого кода предложено не было. Вот мой вывод:
#!/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
источник
Для меня HUP звучит как чушь. Я бы отправил его, чтобы демон перечитал его конфигурацию.
SIGTERM можно перехватить; у ваших демонов просто может быть код очистки для запуска при получении этого сигнала. Вы не можете этого сделать для SIGKILL. Таким образом, с SIGKILL вы не даете автору демона никаких опций.
Подробнее об этом в Википедии
источник