когда я не должен убивать процесс?

<p>я всегда очень не решаюсь бежать <code>kill -9</code>, но я вижу, что другие администраторы делают это почти постоянно.</p><p>я полагаю, что есть разумная золотая середина, поэтому:</p><ol> <li>когда и почему следует <code>kill -9</code> использоваться? когда и почему нет?</li> <li>что нужно попробовать, прежде чем делать это?</li> <li>какая отладка "зависшего" процесса может вызвать дальнейшие проблемы?</li> </ol>

<p>как правило, вы должны использовать <code>kill</code> (сокращение от <code>kill -s term</code> или в большинстве систем <code>kill -15</code>) перед <code>kill -9</code> (<code>kill -s kill</code>), чтобы дать целевому процессу шанс убраться за собой. (процессы не могут поймать или игнорировать <code>sigkill</code>, но они могут и часто действительно ловят <code>sigterm</code>.) если вы не даете процессу возможность завершить то, что он делает, и очистить его, он может оставить поврежденные файлы (или другое состояние), которые он не сможет понять после перезапуска.</p><p><code>strace</code>/<code>truss</code>, <code>ltrace</code> и <code>gdb</code>, как правило, являются хорошими идеями для выяснения, почему застрял процесс. (<code>truss -u</code> на солярисе особенно полезен; я считаю, что <code>ltrace</code> слишком часто представляет аргументы для вызовов библиотеки в непригодном для использования формате.) в solaris также есть полезные <code>/proc</code> инструменты, некоторые из которых были портированы на linux. (<code>pstack</code> часто полезно).</p>

<p>рэндал шварц часто публиковал "бесполезное использование (x)" в списках. один такой пост был о <code>kill -9</code>. это включает причины и рецепт, чтобы следовать. <a href="http://web.archive.org/web/20110730051506/http://partmaps.org/era/unix/award.html#uuk9letter">вот восстановленная версия</a> (цитируется ниже).</p><blockquote> <p>(цитата мерзость)</p> <p>нет нет нет. не используйте kill -9.</p> <p>это не дает процессу возможность чисто:</p> <p>1) отключить разъемы</p> <p>2) очистить временные файлы</p> <p>3) сообщить своим детям, что он уходит</p> <p>4) сбросить свои терминальные характеристики</p> <p>и так далее, и так далее, и так далее.</p> <p>как правило, отправьте 15 и подождите секунду или две, и если это не сработает, отправьте 2, а если это не сработает, отправьте 1. если это не сработает, удалите двойной, потому что программа плохо себя ведет!</p> <p>не используйте kill -9. не берите комбайн, чтобы убрать цветочный горшок.</p> <p>просто еще одно бесполезное использование usenet,</p> <p>(.подпись)</p> </blockquote>

<p>всегда должно быть в порядке, чтобы сделать <code>kill -9</code>, так же, как всегда должно быть в порядке, чтобы отключить, потянув кабель питания. это может быть антиобщественным и оставить некоторое восстановление, но это должно сработать, и это мощный инструмент для нетерпеливых.</p><p>я говорю это как кто-то, кто сначала попробует обычный kill (15), потому что он дает программе шанс выполнить некоторую очистку - возможно, просто записывает в журнал "выход на sig 15". но я не приму никаких жалоб на плохое поведение при убийстве -9.</p><p>причина: многие клиенты делают это с тем, что программисты предпочли бы, а затем нет. случайное уничтожение -9 - хороший и честный сценарий тестирования, и если ваша система не справляется с этим, ваша система сломана.</p>

<p>я использую kill -9 почти так же, как я бросаю кухонные орудия в посудомоечную машину: если кухонный инвентарь разрушен посудомоечной машиной, то я не хочу этого.</p><p>то же самое относится и к <em>большинству</em> программам (даже базам данных): если я не могу их убить, когда дела идут плохо, я действительно не хочу их использовать. (и если вам случится использовать одну из этих не баз данных, которая побуждает вас притворяться, что они сохранили данные, а их нет: я думаю, пришло время подумать о том, что вы делаете).</p><p>потому что в реальном мире все может ухудшиться в любое время по любой причине.</p><p>люди <em>должны</em> написать программное обеспечение, которое терпимо к сбоям. в частности на серверах. вы должны научиться проектировать программное обеспечение, которое предполагает, что что-то сломается, сломается и т.д.</p><p>то же самое касается настольного программного обеспечения. когда я хочу выключить свой браузер, обычно требуется возраст, чтобы выключиться. существует <em>ничего</em> мой браузер <em>нуждается</em>, чтобы сделать это должно занять не более пары секунд. когда я прошу его закрыть, он должен сделать это немедленно. если этого не произойдет, тогда мы вытащим kill -9 и сделаем это.</p>

<p>во всех остальных ответах не упоминается случай, когда <code>kill -9</code> вообще не работает, когда процесс <code><defunct></code> и его невозможно убить:</p><p> <a href="https://unix.stackexchange.com/questions/11172/how-can-i-kill-a-defunct-process-whose-parent-is-init?rq=1">как я могу убить процесс <defunct>, чьим родителем является init?</a> </p><p> <a href="https://askubuntu.com/questions/201303/what-is-defunct-for-a-process-and-why-it-doesnt-get-killed">что такое несуществующий процесс и почему он не убит?</a> </p><p>поэтому перед попыткой <code>kill -9</code> процесса <code><defunct></code> запустите <code>ps -ef</code>, чтобы узнать, кто его родитель, и попытайтесь <code>-15</code> (term) или <code>-2</code> (int) и, наконец, <code>-9</code> (kill) на его родителя.</p><p><sub><strong> примечание: </strong> <a href="http://explainshell.com/explain?cmd=ps%20-ef">что делает <code>ps -ef</code></a> .</sub></p><p><sub><strong> позже отредактируйте и предупредите: </strong> действуйте с осторожностью при уничтожении процессов, их родителей или их дочерних элементов, поскольку они могут оставлять файлы открытыми или поврежденными, соединения незавершенными, могут повреждаться базы данных и т. д., если вы не знаете, что <code>kill -9</code> делает для процесса, используйте его только в качестве крайней меры, и если вам нужно запустить kill, используйте сигналы, указанные выше, прежде чем использовать <code>-9 (kill)</code></sub></p>

<p>никогда никогда не делайте <code>kill -9 1</code>. также избегайте уничтожения некоторых процессов, таких как mount`. когда мне нужно убить много процессов (скажем, например, зависает x-сессия, и мне нужно убить все процессы определенного пользователя), я меняю порядок процессов. например:</p><pre><code>ps -ef|remove all processes not matching a certain criteria| awk '{print $2}'|ruby -e '$a=stdin.readlines; a.reverse.each{|a| puts "kill -9 #{a}"}'|bash </code></pre><p>помните, что <code>kill</code> не останавливает процесс и не освобождает его ресурсы. все, что он делает, это посылает сигнал sigkill процессу; вы можете закончить процесс, который зависает.</p>

<p>убийство процессов волей-неволей не гладкое движение: данные могут быть потеряны, плохо спроектированные приложения могут незаметно сломаться, что не может быть исправлено без переустановки ... но это полностью зависит от знания того, что и что небезопасно в данная ситуация. и что будет в опасности. пользователь должен иметь некоторое представление о том, что делает или должен делать процесс и каковы его ограничения (дисковые операции ввода-вывода в секунду, rss/swap) и уметь оценивать, сколько времени должен занимать длительный процесс (например, копия файла, перекодирование в mp3, перенос электронной почты, резервное копирование, [ваш любимый таймсинк здесь].)</p><p>кроме того, отправка <code>sigkill</code> в pid не гарантирует его уничтожения. если он застрял в системном вызове или уже зомбирован (<code>z</code> in <code>ps</code>), он может продолжать зомбироваться. это часто случается с ^ z длительным процессом и забывает <code>bg</code>, прежде чем пытаться <code>kill -9</code> это. простой <code>fg</code> переподключит stdin/stdout и, вероятно, разблокирует процесс, обычно после чего процесс завершается. если он застрял в другом месте или в какой-либо другой форме тупика ядра, удалить его может только перезагрузка. (процессы zombie уже мертвы после того, как ядро обработало <code>sigkill</code> (дальнейший код пользователя не запускается), обычно есть причина в ядре (похожая на "блокировку", ожидающую завершения системного вызова) для процесса, который не терминатор).</p><p>также, если вы хотите убить процесс и всех его дочерних элементов, попробуйте вызвать <code>kill</code> с <strong>отрицательный pid, а не только сам pid</strong>. нет никакой гарантии, что <code>sighup</code>, <code>sigpipe</code> или <code>sigint</code> или другие сигналы будут очищены после него, а наличие множества отработавших процессов для очистки (помните, монгрел?) раздражает.</p><p><strong>бонус зла: <code>kill -9 -1</code> немного более разрушительно, чем <code>kill -9 1</code> (не делайте ни с правами root, если вы не хотите видеть, что происходит на одноразовой, неважной виртуальной машине)</strong></p>

<p>я создал скрипт, который помогает автоматизировать эту проблему.</p><p>он основан на моем полном ответе <a href="https://stackoverflow.com/a/37692419/670521">2</a> на вопрос, очень похожий на <a href="https://stackoverflow.com/a/37692419/670521">stackoverflow</a> .</p><p>вы можете прочитать все объяснения там. подводя итог, я бы порекомендовал просто <code>sigterm</code> и <code>sigkill</code> или даже <code>sigterm</code>, <code>sigint</code> и <code>sigkill</code>. однако я даю больше вариантов в полном ответе.</p><p>пожалуйста, не стесняйтесь скачать (клонировать) его с github <a href="https://github.com/drbeco/killgracefully">хранилище, чтобы убить изящно</a> <a href="https://github.com/drbeco/killgracefully">1</a> </p>

<h2>почему вы не хотите <code>kill -9</code> процесс нормальный</h2><p>в соответствии с <code>man 7 signal</code>:</p><blockquote> <p>сигналы sigkill и sigstop не могут быть пойманы, заблокированы или проигнорированы.</p> </blockquote><p>это означает, что приложение, которое получает любой из этих сигналов, не может "перехватить" их, чтобы выполнить какое-либо поведение при завершении работы.</p><h2>что вы должны сделать перед запуском <code>kill -9</code> в процессе</h2><p>перед отправкой сигнала процессу вы должны убедиться, что вы:</p><ol> <li>убедитесь, что процесс не занят (т.е. выполняет "работу"); отправка <code>kill -9</code> к процессу по существу приведет к потере этих данных.</li> <li>если процесс является неотзывчивой базой данных, убедитесь, что он сначала очистил свои кэши. некоторые базы данных поддерживают отправку других сигналов процессу для принудительной очистки его кэша.</li> </ol>