Как убить процессы зомби в Linux

Окно терминала на ноутбуке с Linux.
Фатмавати Ахмад Дзэнури / Shutterstock

Плохо написанные или плохо работающие программы могут оставлять зомби-процессы, скрывающиеся внутри вашего Linux-компьютера. Узнайте, как создаются зомби и как их наконец упокоить.

Как состояния процесса работают в Linux

Linux, конечно же, должен отслеживать все приложения и демоны, работающие на вашем компьютере. Один из способов сделать это — поддерживать таблицу процессов. Это список структур в памяти ядра. Каждый процесс имеет запись в этом списке, которая содержит некоторую информацию о нем.

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

Это печатная плата, которая содержит множество деталей, которые Linux необходимо найти или настроить для каждого процесса. Плата также обновляется по мере создания процесса с учетом времени обработки и, наконец, уничтожается.

Печатная плата Linux содержит более 95 полей. Это определено как структура, называемая task_struct.h, и это более 700 строк. Печатная плата содержит следующие типы информации:

  • Состояние процесса: Состояния описаны ниже.
  • Номер процесса: Его уникальный идентификатор в операционной системе.
  • Счетчик команд: Когда этому процессу в следующий раз будет предоставлен доступ к ЦП, система будет использовать этот адрес для поиска следующей инструкции процесса, который должен быть выполнен.
  • Регистры: Список регистров ЦП, используемых этим процессом. Список может содержать аккумуляторы, индексные регистры и указатели стека.
  • Открыть список файлов: Файлы, связанные с этим процессом.
  • Информация о расписании ЦП: Используется для определения того, как часто и как долго процессорное время выделяется на этот процесс. Приоритет процесса, указатели на очереди планирования и другие параметры планирования должны быть записаны на плате.
  • Информация об управлении памятью: Подробная информация о памяти, которую использует этот процесс, например, начальный и конечный адреса памяти процесса и указатели на страницы памяти.
  • Информация о состоянии ввода / вывода: Любые устройства ввода или вывода, используемые процессом.

«Состояние процесса» может быть любым из следующих:

  • Р: Работающий или готовый к выполнению процесс. Запуск означает, что он получает циклы ЦП и выполняется. Готовый к работе процесс готов к запуску и ждет слота ЦП.
  • S: Спящий процесс. Процесс ожидает завершения действия, такого как операция ввода или вывода, или доступности ресурса.
  • D: Процесс находится в состоянии непрерывного сна. Он использует блокирующий системный вызов и не может продолжать работу до завершения системных вызовов. В отличие от состояния «сна», процесс в этом состоянии не будет реагировать на сигналы до тех пор, пока системный вызов не завершится и выполнение не вернется к процессу.
  • Т: Процесс завершен (остановлен), потому что он получил SIGSTOP сигнал. Это буду только отвечать к SIGKILL или SIGCONT сигналы, которые либо завершают процесс, либо предписывают ему продолжить, соответственно. Вот что происходит, когда вы меняете передний план (fg) к задний план (bg) задачи.
  • С УЧАСТИЕМ: Зомби-процесс. Когда процесс завершается, он не исчезает просто так. Он освобождает всю используемую память и удаляет себя из памяти, но его записи в таблице процессов и на плате остаются. Его состояние установлено на EXIT_ZOMBIE, и его родительский процесс уведомляется ( SIGCHLD signal) о завершении дочернего процесса.

В состоянии Zombie родительский процесс вызывает один из wait() семейства функций при создании дочернего процесса. Затем он ждет изменения состояния в дочернем процессе. Был ли дочерний процесс остановлен, продолжен или уничтожен сигналом? Завершилось ли оно естественным завершением своего кода?

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

Что вызывает зомби-процессы в Linux?

Плохо написанный родительский процесс может не вызывать wait() функция при создании дочернего процесса. Это означает, что ничто не отслеживает изменения состояния в дочернем процессе, и SIGCHLD сигнал будет проигнорирован. Или, возможно, другое приложение влияет на выполнение родительского процесса из-за плохого программирования или злого умысла.

Однако, если родительский процесс не следит за изменениями состояния в дочернем процессе, надлежащего обслуживания системы не произойдет. Плата и запись в таблице процессов не будут удалены при завершении дочернего процесса. Это приводит к тому, что состояние зомби никогда не удаляется с печатной платы.

Зомби используют немного памяти, но обычно не представляют проблемы. Запись в таблице процессов небольшая, но, пока она не будет выпущена, идентификатор процесса нельзя использовать повторно. В 64-битной операционной системе это вряд ли вызовет какие-либо проблемы, потому что размер платы намного больше, чем запись в таблице процессов.

Возможно, огромное количество зомби может повлиять на объем памяти, свободной для других процессов. Однако, если у вас так много зомби, у вас серьезная проблема с родительским приложением или ошибка операционной системы.

Как удалить зомби-процессы

Вы не можете убить процесс зомби, потому что он уже мертв. Он не будет реагировать ни на какие сигналы, потому что был удален из памяти — некуда отправлять SIGKILL сигнал. Вы можете попробовать отправить SIGCHLD сигнал родительскому процессу, но если он не сработал при завершении дочернего процесса, вряд ли он сработает и сейчас.

Единственное надежное решение — убить родительский процесс. Когда он завершается, его дочерние процессы наследуются init процесс, который является первым процессом, который запускается в системе Linux (его идентификатор процесса равен 1).

В init process регулярно выполняет необходимую очистку от зомби, поэтому, чтобы убить их, вам просто нужно убить процесс, который их создал. В top command — удобный способ узнать, есть ли у вас зомби.

Введите следующее:

top

вверху в окне терминала

В этой системе восемь зомби-процессов. Мы могу перечислить эти используя ps команда и подключил его к egrep. Опять же, у зомби-процессов есть государственный флаг «Z», и вы обычно также видите «несуществующие».

Введите следующее:

ps aux | egrep "Z|defunct"

пс в |  egrep "Z | несуществующий" в окне терминала

Перечислены зомби-процессы.

Выход из ps aux |  egrep "Z | несуществующий" в окне терминала

Это более удобный способ узнать идентификаторы процессов зомби, чем прокрутка назад и вперед. top. Мы также видим, что этих зомби породило приложение под названием «badprg».

Идентификатор процесса первого зомби — 7641, но нам нужно найти идентификатор процесса его родительского процесса. Мы можем сделать это, используя ps еще раз. Мы будем использовать параметр вывода (-o) сказать ps чтобы отобразить только идентификатор родительского процесса, а затем передать его с ppid= флаг.

Процесс, который мы хотим найти, будет обозначен с помощью -p (process) вариант, а затем передать идентификатор процесса зомби.

Поэтому мы вводим следующую команду для поиска информации о процессе 7641, но она будет сообщать только идентификатор родительского процесса:

ps -o ppid= -p 7641

ps -o ppid = -p 7641 в окне терминала

Нам сказали, что идентификатор родительского процесса — 7636. Теперь мы можем ссылаться на него, используя ps еще раз.

ps -e |  grep 7636 в окне терминала

Мы видим, что это соответствует названию родительского процесса ранее. Чтобы убить родительский процесс, используйте параметр SIGKILL с командой kill следующим образом:

kill -SIGKILL 7636

В зависимости от владельца родительского процесса вам также может потребоваться sudo.

Зомби не страшны…

… Если они не в огромной орде. О некоторых не стоит беспокоиться, и простая перезагрузка уничтожит их.

Однако, если вы заметили, что приложение или процесс всегда порождают зомби, вам следует изучить это. Скорее всего, это просто небрежно написанная программа, и в этом случае, возможно, есть обновленная версия, которая должным образом очищается после своих дочерних процессов.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован.