Большинство описаний SIGTERM и SIGKILL указывают на то, что SIGKILL,
В отличие от SIGTERM и SIGINT, [...] не может быть перехвачен или проигнорирован [...] (Википедия)
Это единственное различие между SIGTERM и SIGKILL? В частности, если процесс не устанавливает обработчик SIGTERM, есть ли вообще разница между отправкой SIGTERM или SIGKILL процессу?
решение1
При отсутствии какой-либо конфигурации сигнала SIGTERM
и SIGKILL
на практике эквивалентны, по крайней мере с точки зрения завершенного процесса, как и другие сигналы, действие которых по умолчанию заключается в завершении процесса, включая SIGUSR1
и SIGUSR2
.илккачууказывает, родительский процесс информируется о сигнале, который завершил дочерний процесс (именно так ваша оболочка может различать сигналы и печататьнапример«завершено» против «определенного пользователем сигнала 1»).
Как упоминается в Википедии, SIGKILL
нельзя перехватить или проигнорировать, тогда как SIGTERM
можно; обратите внимание, что это означает, что процессу не нужно устанавливать обработчик, чтобы SIGTERM
быть неэффективным, он может просто заблокировать его или проигнорировать (см.sighold()
, sigrelse()
иsigignore()
).
POSIX как подробный раздел пообоснование обработки сигнала. Линуксsignal(7)
man-страница также подробно документирует сигналы.
решение2
Это единственное различие между SIGTERM и SIGKILL?
Нет.
Большая разница между a SIGKILL
и uncaught SIGTERM
заключается в том, что первый также будетпроснутьсяостановленный процесс (чтобы он мог немедленно уничтожить себя), в то время как последний вступит в силу только после SIGCONT
.
Простой пример:
$ sleep 1000 & sleep 1; kill -TSTP $!
[1] 6455
[1]+ Stopped sleep 1000
$ kill -TERM 6455
$ jobs
[1]+ Stopped sleep 1000
$ kill -CONT 6455
$ jobs
[1]+ Terminated sleep 1000
Если вы хотите быть уверены, что ваш сигнал TERM
, HUP
, INT
, и т. д. имеет какой-либо эффект, вам следует связать его с CONT
сигналом (в любом порядке).
Люди могут не сразу это понять из-за магии встроенной функции bash kill
— при использовании с идентификатором задания, например, %
или %1
(или с отрицательным pid), ссылающимся на остановленный процессработа, это будетсделать все это самза кулисами:
/* Give PID SIGNAL. This determines what job the pid belongs to (if any).
If PID does belong to a job, and the job is stopped, then CONTinue the
job after giving it SIGNAL. Returns -1 on failure. If GROUP is non-null,
then kill the process group associated with PID. */
int
kill_pid (pid, sig, group)