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

Опубликовано: 2022-01-29
Окно терминала на ноутбуке с Linux.
Фатмавати Ахмад Заэнури/Shutterstock

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

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

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

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

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

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

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

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

  • R: запущенный или работающий процесс. Запуск означает, что он получает циклы ЦП и выполняется. Запускаемый процесс готов к запуску и ожидает слота ЦП.
  • СУБЪЕКТ: Спящий процесс. Процесс ожидает завершения действия, например операции ввода или вывода, или освобождения ресурса.
  • D: Процесс находится в непрерывном спящем состоянии. Он использует блокирующий системный вызов и не может продолжать работу, пока системные вызовы не будут завершены. В отличие от состояния «Сон», процесс в этом состоянии не будет реагировать на сигналы до тех пор, пока системный вызов не завершится и выполнение не вернется к процессу.
  • T: Процесс завершен (остановлен), так как он получил сигнал SIGSTOP . Он будет реагировать только на сигналы SIGKILL или SIGCONT , которые либо завершат процесс, либо предложат ему продолжить работу соответственно. Вот что происходит, когда вы переключаетесь с задач переднего плана ( fg ) на фоновые ( bg) .
  • Z: Процесс зомби. Когда процесс завершается, он не просто исчезает. Он освобождает всю используемую им память и удаляет себя из памяти, но его запись в таблице процессов и на плате остается. Его состояние устанавливается на EXIT_ZOMBIE , а его родительский процесс уведомляется (сигналом SIGCHLD ) о завершении дочернего процесса.

Реклама

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

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

СВЯЗАННЫЕ С: Как запускать и контролировать фоновые процессы в Linux

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

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

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

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

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

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

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

Реклама

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

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

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

 верхняя 

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

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

 PS вспомогательный | egrep "Z|несуществующий" 

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

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

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

Реклама

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

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

 ps -o ppid= -p 7641 

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

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

 убить -SIGKILL 7636

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

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

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

Реклама

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