Знакомство с семейством операционных систем Linux сопряжено пониманием особенностей управления процессами в этой системе. Процесс — это программа, которая, по сути, выполняется постоянно.
Программа, которая не выполняется, не считается процессом, поскольку она находится в пассивном состоянии. Состояние выполнения делает его активным объектом, следовательно, процессом. Также стоит отметить, что выполнение одной программы может быть связано с несколькими процессами.
Давайте определим два типа процессов:
Интерактивные процессы. За инициализацией и выполнением этих процессов стоит пользователь или программист. Системные службы не несут ответственности за их работу. Эти процессы возвращают выходные данные из ввода пользователя. Если процесс уже запущен, невозможно напрямую инициировать новый из того же терминала.
Фоновые процессы или неинтерактивные процессы. За их инициирование и выполнение несут ответственность системные службы или пользователи. Пользователи системы также могут управлять ими. Каждому из этих процессов присваивается уникальный идентификатор процесса (PID).
Состояние процесса.
В таблице процессов можно найти несколько состояний процессов.
- Running (R) — это запущенные и активные процессы в данный момент.
- Waiting (W) — это процессы, которые ожидают освобождение ресурсов или каких-либо событий. Такое ожидание может быть либо непрерывным спящим режимом (D), либо прерываемым (S)
- Stopped (T) — запущенный процесс остановлен соответствующим сигналом.
- Zombie(Z) — Это процессы, которые еще существуют в таблице процессов, несмотря на то, что они уже выполнили назначенные им задачи.
Как появляются зомби-процессы
Как только процесс завершает назначенную ему задачу, родительский элемент этого процесса уведомляется ядром Linux через сигнал SIGCHLD. Перед чтением кода завершения дочернего процесса, выполняется системный вызов wait() для считывания его состояния.
Эта цепочка событий приводит к очистке записи дочернего процесса из таблицы процессов. Однако, когда родительский процесс не может обработать сигнал SIGCHLD, связанный с дочерним процессом, создается процесс-зомби.
Определение процесса зомби.
Для определения процесса зомби, можно использовать команду ps.
user@host1:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 2.8 1.2 101900 12652 ? Ss 19:02 0:03 /sbin/init root 2 0.0 0.0 0 0 ? S 19:02 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? I< 19:02 0:00 [rcu_gp] root 4 0.0 0.0 0 0 ? I< 19:02 0:00 [rcu_par_gp] root 5 0.0 0.0 0 0 ? I< 19:02 0:00 [slub_flushwq] root 6 0.0 0.0 0 0 ? I< 19:02 0:00 [netns] root 7 0.0 0.0 0 0 ? I 19:02 0:00 [kworker/0:0-rcu_gp] root 8 0.0 0.0 0 0 ? I< 19:02 0:00 [kworker/0:0H-events_highpri] root 9 0.6 0.0 0 0 ? I 19:02 0:00 [kworker/u2:0-events_unbound] root 10 0.0 0.0 0 0 ? I< 19:02 0:00 [mm_percpu_wq] root 11 0.0 0.0 0 0 ? S 19:02 0:00 [rcu_tasks_rude_] root 12 0.0 0.0 0 0 ? S 19:02 0:00 [rcu_tasks_trace] root 13 0.1 0.0 0 0 ? S 19:02 0:00 [ksoftirqd/0] root 14 0.5 0.0 0 0 ? I 19:02 0:00 [rcu_sched] root 15 0.0 0.0 0 0 ? S 19:02 0:00 [migration/0] root 16 0.0 0.0 0 0 ? S 19:02 0:00 [idle_inject/0] root 17 0.1 0.0 0 0 ? I 19:02 0:00 [kworker/0:1-cgroup_destroy] root 18 0.0 0.0 0 0 ? S 19:02 0:00 [cpuhp/0] root 19 0.0 0.0 0 0 ? S 19:02 0:00 [kdevtmpfs] root 20 0.0 0.0 0 0 ? I< 19:02 0:00 [inet_frag_wq] ...
Если вы обнаружите любую запись Z в столбце STAT, значит, вы имеете дело с процессом-зомби.
В качестве альтернативы можно передать команду ps через команду awk, чтобы отфильтровать любые процессы-зомби (Z) в вашей системе.
user@host1:~$ ps aux | awk '{if($8=="Z+") print}' root 3527 0.0 0.0 0 0 pts/1 Z+ 19:17 0:00 [zombie]
Как убрать процессы зомби.
Процесс зомби, на то так и зовется, что он уже мертв, и обычной командой kill его не убить. Но применяя знания о том, что такое зомби-процесс, есть решение по очистки таблицы процессов от зомби.
Мы можем вручную отправить SIGHLD родительскому процессу процесса-зомби, чтобы инициировать системный вызов wait() из этого родительского процесса. Такой подход дает возможность убрать из таблицы процессов несуществующую запись дочернего процесса.
Первым шагом является определение родительского идентификатора несуществующего процесса.
user@host1:~$ ps -A -ostat,pid,ppid | grep -e '[zZ]' Z+ 3543 3542
Если в вашей системе есть процесс-зомби, приведенная выше команда должна соответствующим образом перечислить связанный столбец STAT, идентификатор процесса и идентификатор родительского процесса.
В приведенном выше примере вывода 3542 — это идентификатор родительского процесса (ppid), и чтобы очистить процесс-зомби, надо выполнить:
# kill -s SIGCHLD 3542
Правда, приведенный выше подход очищает процесс-зомби только в том случае, если родительский процесс успешно обрабатывает сигналы SIGCHLD.
В противном случае можно убить родительский процесс 3542, что автоматически избавит нас от процессов-зомби:
# kill -9 3542
Теперь мы можем с легкостью избавляться от зомби в нашей системе Linux. Надеюсь было полезно.
Was this helpful?
0 / 0