Не используйте kill -9

Original author: Jeremy Mates
  • Translation
Аргумент -9 (или KILL) для команды kill следует использовать в POSIX-совместимых системах только в случае крайней необходимости. Почему? Сигнал KILL не может быть обработан процессом. Это означает, что после завершения процесса с помощью kill -9, дочерние процессы останутся в памяти и станут «осиротевшими» (orphaned), файловая система окажется засорена временными файлами, сегменты совместно используемой памяти — активными, сокеты — зависшими, а функция atexit(3) вообще не будет выполнена. В результате есть риск столкнуться с неожиданными и сложными для отладки проблемами.

Вместо этого используйте дефолтный сигнал TERM, а KILL — только если менее проблемные сигналы окажутся неэффективными:

$ kill 6738
$ kill -INT 6738
$ kill -HUP 6738
$ kill -KILL 6738

Если даже сигналу KILL не удается завершить процесс, это означает, что процесс скорее всего завис при операции ввода-вывода или находится в каком-нибудь другом незавершаемом состоянии. Может потребоваться перезагрузка или принудительное размонтирование глючного сетевого диска.

Использование kill -KILL по умолчанию допустимо при работе с проблематичным приложением, например, старые версии Netscape частенько завершались только с помощью сигнала KILL. Однако, это редкое исключение из правила: используйте KILL для этих заранее известных приложений и только для них.

Проблемы, возникающие при завершении процессов


Последовательная отправка разных сигналов может вызвать следующие проблемы: во-первых, процессу могут потребоваться секунды, или даже десятки секунд для корректного завершения. Один продукт, которым мне приходилось пользоваться, требовал более 30 секунд для правильного завершения после получения сигнала TERM. К счастью, эта особенность была обнаружена во время тестирования, поэтому для этого случая был написан подходящий скрипт. Во-вторых, иногда бывают ситуации, когда старый процесс завершился, в то время как новый процесс занял его ID в промежутке между сигналами TERM и KILL. Особенно этому риску подвергаются системы с повышенной «текучкой» процессов и системы, где ядро назначает PID в случайном порядке, например, OpenBSD. Проверка имени процесса или его PPID не всегда помогает, так как новый процесс может быть форком того же родителя и иметь такое же имя, поэтому особо параноидальные скрипты могут также проверять время создания процесса или другие метаданные перед отправкой сигнала. Возможно эти ситуации возникают редко, но с ними стоит считаться, если приходится иметь дело с критичным процессом.

Сигналы завершения процесса


Сигналы завершения процесса могут обозначаться по имени или порядковому номеру: kill -1 и kill -HUP эквивалентны. Однако, использование имени сигнала более безопасно, так как при указании аргумента -1 легко опечататься, отправив сигнал другому процессу или даже группе процессов. Также всегда старайтесь использовать имя в скриптах, так как это поможет лучше понять какой тип сигнала отправляется тому, кто будет читать ваш код.

Сигнал HUP «подвешивает» шелл, поэтому это хороший способ очистить шелл, повисший в ожидании ввода, или закрыть SSH-сессию.

Более подробная информация о сигналах завершения процессов указана в man-страницах kill(1), а команда kill -l выведет список сигналов, поддерживаемых операционной системой. kill(2) детально описывает системные вызовы. Для более подробной информации, обратитесь к книгам The Design and Implementation of the 4.4 BSD Operating System или UNIX Internals: The New Frontiers.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 68

    –1
    Так как все таки кошерно убивать процессы? Что посоветуете?
    Про kill -9 и оставшиеся процессы не знал.
      +1
      kill -15 pid
        +2
        kill PID (-15 или -TERM используются по умолчанию). Если же этот вариант не помог, попробуйте убить процесс, посылая сигналы в порядке «силы», как описано в статье, учитывая, что процессу может потребоваться некоторое время для корректного завершения.
          0
          Все упирается в то какие сигналы приложение обрабатывает само, а какие отдает на обработку ОС. Единственный сигнал который приложение «не имеет право» перехватывать это -9 (KILL). И еще если не изменяет память ABR. В целом есть такая полезная штука man signal… Можно почитать на досуге. Но то как ведет себя программа при посылке сигнала определяет во многом приложение, а не то что написано где либо.
          –3
          А killall разве не делает именно это? Вначале TERM, потом HUP и KILL?
            +4
            Нет, программа killall убивает все процессы с данным именем, по умолчанию отправляя сигнал TERM. Тип сигнала указывается так же, как и для команды kill
              +1
              killall sends a signal to all processes running any of the specified commands. If no signal name is specified, SIGTERM is sent.
              Разница между kill и killall только в том, что 1-ый убивает конкретный процесс (по pid'у), а 2-ой убивает все процессы с одинаковым именем (или по регулярке).
                +9
                Вы только в Solaris killall не набирайте :) Он делает именно то, что написано в названии команды.
                  +3
                  Хорошо хоть, если набрать killall httpd в Солярке он ругается на аргумент, а не начинает всех мочить.
                    0
                    debian/ubuntu — killall5 называется )
                    а killall в чистой системе нету ))) есть в пакете psmisc
                      –4
                      Я тебя ненавижу.
                        +1
                        «Вы все еще сидите под рутом? тогда мы идем к Вам!»
                          0
                          оно и без рута делов наделало. Вот дурная привычка все попробовать. (rm -rf не предлагать)
                      +1
                      Дык и что получается в итоге? Остаётся ядро оси без единого процесса? Зачем такая комманда нужна?
                        0
                        Она вызывается процессом shutdown. Завершает все процессы, не задействованные непосредственно в процессе shutdownа, после чего можно отмонтировать файловые системы.
                        0
                        Используйте pkill ( [pattern] kill ).
                          0
                          Всегда интересовало чем оно отличается от киллолла, и всегда было лениво посмотреть ))
                            0
                            Ну он по куску убивает.
                            Например pkill ftp убьет как ftp так и proftpd :)
                      0
                      Перенес топик в блог «Linux для всех», так как он самый читаемый. Блога POSIX, к сожалению, нет, а блог, посвящённый Unix, судя по контенту предназначен для постов о том самом Юниксе.
                        –7
                        Читаю RSS, в наушниках <a href=«graphics.stanford.edu/~monzy/KillDashNine.mp3>песня, а на хабре тоже про kill dash nine. Не к добру это.
                          –3
                          Ой.
                            –2
                            Вот тебе и ой
                          +2
                          спасибо, но man kill покороче и информативнее
                            +3
                            Тема поста: «Не используйте kill -9». В man kill информативнее рассказывается о последствиях применения -9? Мне казалось, там ничего про это нет.
                              +10
                              Здесь о последствиях тоже не особо рассказывается, только довольно-таки параноидальное «дочерние процессы останутся в памяти и станут «осиротевшими» (orphaned), файловая система окажется засорена временными файлами, сегменты совместно используемой памяти — активными, сокеты — зависшими, а функция atexit(3) вообще не будет выполнена». Сразу же хочется спросить «и что?» Чем это грозит простому обывателю? /tmp и так забивается, потому что не все программы аккуратно чистят за собой временные файлы, сокеты отвалятся по тайм-ауту. Привели бы пример реального вреда с реальными и не криво написанными приложениями, когда kill -9 может повлечь за собой существенные проблемы, которых можно избежать, используя другие сигналы.
                                0
                                Но это уже больше, чем написано в man. Именно про это я и писал (см. комментарий выше).

                                Ну а простому обывателю достаточно слов «засорена» и «зависшими» и что все это плохо. Интересующиеся темой более углубленно скорее всего уже знают, что это значит и не поленятся посмотреть man 3 atexit. Да и что теперь, разжевывать каждый технический пост для всех?
                                  +8
                                  Так блог же называется Linux _для всех_ =)
                                    +4
                                    >Да и что теперь, разжевывать каждый технический пост для всех?
                                    А каков тогда смысл этого поста?
                                      –1
                                      Главная мысль — применять -9 плохо, она объяснена. Написано, чем это грозит. А если нужны объяснения терминов и подробности, то можно и самостоятельно поискать и углубиться в тему. Тем более, что на основе такого поста сделать это легче.

                                      А может здесь еще расписать, что такое сигналы, что это вообще за команда kill? Мне кажется, это тема отдельного обсуждения. Тут специфичный вопрос рассматривается.
                                        +2
                                        >Главная мысль — применять -9 плохо, она объяснена.
                                        Плохо применять её без достаточных на то оснований. А настолько пространное объяснение ситуации с SIGKILL дано в любой книге о Линукс.
                                        >Написано, чем это грозит.
                                        "… иначе ваш компьютер может выйти из строя".
                                          0
                                          дочерние процессы останутся в памяти и станут «осиротевшими» (orphaned), файловая система окажется засорена временными файлами, сегменты совместно используемой памяти — активными, сокеты — зависшими, а функция atexit(3) вообще не будет выполнена

                                          Где здесь «пространное»? Одна конкретика.
                                          0
                                          >Главная мысль — применять -9 плохо, она объяснена.
                                          Плохо применять её без достаточных на то оснований. А настолько пространное объяснение ситуации с SIGKILL дано в любой книге о Линукс.
                                          >Написано, чем это грозит.
                                          "… иначе ваш компьютер может выйти из строя".
                                      +7
                                      Сразу же хочется спросить «и что?» Чем это грозит простому обывателю?
                                      Действительно. Написали бы проще: «Всякий раз, когда вы используете kill -9, Бог убивает котёнка (у которого, как известно, 9 жизней)». Было бы гораздо нагляднее ;)
                                        +5
                                        Страшно подумать, что делают с котятами при выполнении fork…
                                          +3
                                          Тыкают в них вилкой.
                                    0
                                    man signal видимо не видели…
                                    0
                                    killall NAME?
                                      +1
                                      Самое удобное для меня: killall имя_процесса, так как при наборе имени процесса очень хорошо помогает bash_completion
                                      Меня интересует другое: что надо отправить (какой сигнал) firefox'у, чтобы он не сбрасывал кеш?
                                        +3
                                        Капитан Очевидность?
                                        Каждый должен сам прочитать ман по используемой приложухе и понять, какой сигнал использовать. А пока не видно разницы — зачем использовать что-то кроме SIGKILL?
                                          0
                                          Так здесь же и написано, в чем разница в общем случае, для тех, кто ее не видит.
                                          +9
                                          а я крестиком окошки закрываю…
                                            0
                                            А я привык pkill — 9 -f <название>, ну ничего с собой поделать не могу :-(
                                              +2
                                              отвыкай, фигли)
                                              больше тут ничего не скажешь — kill -kill нужен в 1 случае из 100 и является звоночком «а что это за приложение такое глючное?»
                                                +3
                                                Да тут скорее в лени дел. Гарантированно убить и забыть или отправлять запрос на закрытие, а потом еще ждать и контроллировать, убился ли там процесс.
                                                  0
                                                  Суть в том, что kill -9 безусловно быстрее и надежнее, но он не убъет lock файл приложения (если таковой имеется) и следующий запуск программы может быть проблематичным.
                                                    –1
                                                    Бывало, с предыдущей версией Weblogic. Лечилось чтением лога и удалением lock-файла. Больше приложений таких не встречал и от привычки не отказался.
                                              +5
                                              а что, кто-то убивает процесссы SIGKILL'ом до попытки завершить его стандартными средствами?
                                                –1
                                                +1 =)
                                                  0
                                                  Обычно так происходит в скриптах, когда правильнее сделать очередно. «Так ведь быстрее»
                                                    +2
                                                    Посмотрел бы я, как вы будете неспеша перебирать другие сигналы на тормозном терминале на другой конец мира в тот момент, когда взбесившаяся софтина гадит гигабайты на винт ;-)
                                                      +1
                                                      А если SIGSTOP и потом уже разбираться?
                                                        0
                                                        Как я понимаю, статья о том, что если сидишь сервере, отредактировал конфиг, и внезапно захотелось рестартнуть mysql, то не надо делать killall -9 mysqld, а нужно рестартнуть его своими средствами.

                                                        Когда LA — 1000, и надо что-то сделать, пока не отвалился ssh — то да, kill -9 спасает.
                                                          0
                                                          Тогда, вероятно, стоило дописать про всякие init.d/blahblah start|stop. С mysql там ещё mysqld_safe есть, который его перезапустит, так что задача уничтожения mysqld может так не решиться :-)
                                                        +1
                                                        Mac OS X 10.6 при шатдауне — в случае, если приложение заранее согласилось на такую возможность.
                                                        +1
                                                        Во-первых, даже при SIGTERM временные файлы сами никуда не денутся. Они удалятся только в том случае, если приложение позаботилось о том, чтобы поставить соответствующий обработчик на выход. Или, что лучше, удалило их сразу после создания и открытия.

                                                        Во-вторых, и от SIGKILL бывает польза. Например, его любит Mac OS 10.6: tinyurl.com/n2vpcu
                                                          +1
                                                          Глаза открыли прям. Всю жизнь пользовал kill -9 по не знанию.
                                                          Не до конца понял фразу «Сигнал HUP «подвешивает» шелл, поэтому это хороший способ очистить шелл, повисший в ожидании ввода, или закрыть SSH-сессию.» Как подвешивание может быть способом очистить?
                                                            0
                                                            Будто SIGKILL кто-то использует просто так. Обычно то говно, которое приходится так прибивать, не ставит сигхендл на SIGTERM :]
                                                              0
                                                              Живой пример можете увидеть постом выше. Ну хоть кому-то этот топик помог…
                                                              +12
                                                              Платиновые К.О.-треды на хабре.
                                                                0
                                                                Как то столкнулся с проблемой, что kill -9 не убивал процесс. Как выяснилось — если процесс в состоянии UNINTERUPTABLE — даже kill -9 не поможет.

                                                                С обсуждения понравелась метафора про kill:

                                                                SIGTERM передается процессу, чтобы он умер сам (император приказал совершить сеппуку). SIGKILL отрабатывается ядром (император послал наемного убийцу) (с) no-dashi
                                                                  –3
                                                                  основная идея: не используйте kill -9, т.к. всякие кривые линуксные приложения (которыми система набита до отказа) будут глючить ещё больше, чем обычно
                                                                    –1
                                                                    kill -9 windows-*
                                                                    +2
                                                                    Это означает, что убивая процесс с помощью kill -9, дочерние процессы останутся в памяти и станут «осиротевшими» [...]

                                                                    Ну честное слово, невозможно читать такие предложения.
                                                                    Кто убивает процесс? Дочерние процессы?
                                                                    Если уж так хочется использовать деепричастный оборот — согласуйте его, это же не сложно.
                                                                      +1
                                                                      Спасибо за замечание, исправил.
                                                                      0
                                                                      последний совет весьма актуален. Я сам пишу kill -HUP с тех пор, как однажды убил init (kill 1)
                                                                      :)
                                                                        0
                                                                        все вы написали правильно, не надо килл -9, но бывает что приходится и тогда:

                                                                        > Это означает, что после завершения процесса с помощью kill -9, дочерние процессы останутся в памяти и станут «осиротевшими» (orphaned)…

                                                                        дык
                                                                        ps -ef
                                                                        покажет искомые процессы. Там в колонке PID — ID процесса, а в PPID — ID процесса-родителя. После чего если у нас несколько процессов с одним и тем же именем, то смотрим на время исполнения и время запуска (в след колонках) и убиваем всех родителей/потомков kill -9
                                                                          0
                                                                          очевидно что лучше сразу
                                                                          ps -ef | grep — выведет не только зависший процесс-родитель, но и те процессы для которых он является папой
                                                                            0
                                                                            используйте pkill
                                                                            если надо посмотреть, что процесс породил, то лучше использовать htop, в котором по F5 показывается дерево.

                                                                        Only users with full accounts can post comments. Log in, please.