Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Процессы в Linux

Kill: Завершение неконтролируемых процессов

Оригинал: Killing With Linux: A Primer
Автор: Carla Schroder
Дата: 3 августа 2008
Свободный перевод: Алексей Дмитриев
Дата перевода: 8 сентября 2008


Вы усердно боретесь с особо заковыристым приложением Линукс. Продираясь через дебри документации, запускаете команды и правите конфигурационные файлы. Все работает, и жизнь прекрасна... Как вдруг вас ошарашивает сообщение "send the process a SIGHUP" (пошлите процессу SIGHUP).

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

Когда получен сигнал о том, что программа зависла - SIGHUP, sshd перечитывает свой конфигурационный файл путем запуска самой себя с теми же именем и опциями, с которыми была первоначально запущена, например, /usr/sbin/sshd.

Г-м-м. Хорошо.

Программисты против пользователей

Авторы страниц руководств (манов) делятся на две категории. Одни адресуются конечным пользователям, а другие - "крутым" программистам. Вот почему встречаются заявления типа: "список do будет в работе до тех пор, пока последняя команда в этом списке не выдаст ненулевой выходной статус". Прочитать такое также приятно и полезно, как и "пошлите процессу SIGHUP". Не переживайте, сегодня мы прольем свет на эти тайны, покрытые мраком.

Сигналы и контроль над процессами

Одной из задач опытных администраторов и пользователей является запуск, остановка и перезапуск сервисов, а также остановка сбойных и зависших процессов, причем с минимальным уроном. В различных операционных системах, а также в различных командных оболочках (шеллах) способы управления сигналами сильно рознятся. Поэтому в этой статье мы остановимся на ОС Linux и bash shell.

Сигналы нужны для того, чтобы взаимодействовать с процессами и демонами. Процессом называется любое активное действие. Демоны являются фоновыми (background) процессами, и до поры скрыты. Они ждут либо события, на которое они отреагируют, либо наступления времени, назначенного для выполнения некоего задания по расписанию. О наступлении этого события они узнают, получая сигнал от какого-то другого процесса. Каждая программа должна иметь в своем коде обработчик сигналов, чтобы отслеживать (перехватывать) сигналы и правильно реагировать на них. Страница руководства man signal описывает всевозможные сигналы и их действия. Сигналы посылают при помощи команды kill ("убить"). Команда kill -l выводит список сигналов и их номеров.

Все демоны и процессы имеют Идентификатор Процесса (PID). PID процесса можно узнать при помощи команды ps:

$ ps aux
USER       PID %CPU %MEM TTY  STAT  COMMAND
root         1  0.0  0.1  ?    S    init '2'
105       7783  0.0  0.2  ?    Ss   /usr/bin/dbus-daemon --system
hal       7796  0.0  0.7  ?    Ss   /usr/sbin/hald
postfix   7957  0.0  0.2  ?    S    qmgr -l -t fifo -u -c
nagios    8371  0.0  0.2  ?    SNs  /usr/sbin/nagios /etc/nagios/nagios.cfg

В приведенном выше примере, вывод команды сильно сокращен - в вашей системе вы увидите куда больше строк и столбцов. Если какой-нибудь процесс "ворует" мощность вашего процессора или вашу память, вы увидите это в столбцах %CPU и %MEM.

Еще быстрее "зарвавшийся" процесс можно обнаружить при помощи команды top. В ней, по умолчанию, процессы, потребляющие больше ресурсов процессора, расположены в верхних строках таблицы. Мы можем немного поиграть с программой top при помощи команды yes:

$ yes carla is teh awesum

Эта команда станет повторять "carla is teh awesum" с большой скоростью, пока вы ее не остановите. Она загонит процент использования процессора в красную зону:

$ top
...
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
12144 carla     25   0 31592  17m  13m R 93.4  3.5   0:50.26 konsole
22236 carla     15   0  2860  468  400 S  4.3  0.1   0:00.97 yes

Интересно, что ответственность за разбазаривание мощности CPU ложится на консоль, а не на программу yes, так как yes работает внутри консоли. Если вы перейдете на "истинную" консоль (Ctrl+Alt+F2), то там увидите программу yes с большими цифрами потребления мощности процессора и использования памяти.

Существует несколько способов остановить yes. Если вы перейдете обратно в шелл, где она работает, просто нажмите Ctrl+C. Вы можете также остановить ее при помощи команды kill в другом шелле, как по PID, так и по имени:

$ kill 22236
$ killall yes

Ctrl+C посылает с клавиатуры сигнал SIGINT (2), или завершающее прерывание (terminate interrupt). kill и killall, оба, шлют по умолчанию SIGTERM (15). SIGTERM (15) может быть перехвачен и, либо игнорирован, либо интерпретирован иначе. Так что, в случае непредсказуемой работы, вы можете не добиться завершения процесса.

Применяя команду kill к родительскому процессу, вы, как правило (но не всегда), завершаете дочерний вместе с ним. Как узнать, какой процесс является дочерним? Используйте команду ps с опцией -f :

$ ps axf
22371 ?        R      2:35  _ konsole 'kdeinit'
22372 pts/3    Ss     0:00  |   _ /bin/bash
24322 pts/3    S+     0:00  |   |   _ yes carla is teh awesum
22381 pts/4    Rs     0:00  |   _ /bin/bash
24323 pts/4    R+     0:00  |   |   _ ps axf

Вернемся к нашим SIGHUP'ам

SIGHUP произносится как "сиг-ап" и означает "сигнал отбоя" (signal hangup). Как послать SIGHUP? Существует несколько способов:

  • # kill -HUP 'pid'
  • # killall -HUP 'process-name'
  • # kill -1 'pid'
  • # killall -1 'process-name'

Как видите, можно использовать PID или имя процесса, а также имя или номер сигнала.

Зачем применять все эти команды, когда можно перезапустить процессы при помощи команды /etc/init.d/foo restart? Ведь предпочтительней контролировать сервисы с помощью их файлов init, так как такой контроль обычно включает санацию, проверку ошибок и другие функции. Если говорить честно, то главная причина использовать команду kill и сигналы состоит в том, чтобы остановить зависший или сбойный процесс как можно аккуратнее, и не прибегать к перезагрузке или завершению сеанса.

Применение команды kill к процессам

Как можно видеть в man signal, существуют десятки способов контролировать процессы. Вот наиболее часто применяемые:

kill -STOP 'pid'
SIGSTOP (19) останавливает процесс, не "убивая" его.

kill -CONT 'pid'
SIGCONT (18) перезапускает остановленный процесс.

kill -KILL 'pid'
SIGKILL (9) форсирует немедленное завершение процесса, и не производит никакой чистки.

kill -9 -1
Завершает все ваши процессы (которыми вы владеете).

SIGKILL и SIGSTOP не могут быть перехвачены, блокированы или игнорированы; остальные могут. Это ваше "большое ружье", последнее средство обороны.

Команда kill, встроенная в Bash

Оболочка Bash имеет встроенную команду kill, как показано в следующем листинге:

$ type -all kill
kill is a shell built-in
kill is /bin/kill

Маловероятно, что у вас возникнут конфликты или странное поведение программ, но на всякий случай выбирайте /bin/kill.

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

Ресурсы

  • Глава 7 "Starting and Stopping Linux", Поваренная книга Линукс (the Linux Cookbook)
  • bash (1) - GNU Bourne-Again Shell
  • yes (1) - повторно выводит строку, пока не будет остановлена
  • signal (7) - список сигналов
  • ps (1) - мгновенный снимок идущих процессов
  • kill (1) - посылает сигнал процессу
  • killall (1) - "убивает" процесс по имени
  • pkill (1) - ищет или дает сигнал процессам на основе имени или других атрибутов
  • skill (1) - посылвет сигнал, либо рапортует о статусе процесса
  • xkill (1) - "убивает" клиента по его Х ресурсу



Средняя оценка 5 при 1 голосовавших