Где посмотреть состояние и как выглядит STAT
Состояние процесса видно в столбце STAT вывода ps aux, а также в столбце S команды top. Чтобы получить компактную картину, выведите только нужные колонки: ps -eo pid,ppid,stat,comm. Первая буква в STAT это основное состояние, а следующие символы, если они есть, уточняют детали.
Вариантов в разных системах немного, и они сходны, но не совпадают полностью. Поэтому таблица ниже содержит основное, а редкие случаи уточняйте в man ps в разделе о кодах состояния процесса.
| Код | Смысл | Системы |
|---|---|---|
| R | выполняется или готов выполняться | обе |
| S | спит, ожидает события, может быть разбужен сигналом | обе |
| D | непрерываемое ожидание, обычно ввод-вывод | Linux |
| U | непрерываемое ожидание | macOS |
| I | простаивающий поток ядра (Linux) или процесс, спящий долго (macOS) | обе, но значение разное |
| T | остановлен сигналом или отладчиком | обе |
| Z | зомби, завершён, но не принят родителем | обе |
Условная строка: «Ss» означает спящий процесс, лидер сеанса. Больше символов не значит больше проблем: чаще всего это обычные уточнения.
Дополнительные символы после первой буквы
После основной буквы ps может добавлять символы, поясняющие положение процесса. В Linux встречаются такие.
- < процесс с повышенным приоритетом, то есть отрицательным значением nice.
- N процесс с пониженным приоритетом.
- s лидер сеанса.
- l многопоточный процесс.
- + процесс принадлежит группе переднего плана терминала.
- L страницы заблокированы в памяти.
Состав символов и их смысл зависят от реализации, поэтому не воспринимайте таблицу как исчерпывающую. Расшифровка конкретной версии находится в справке.
Практический вывод для чтения: на первых порах достаточно смотреть на первую букву. Если в списке сотни процессов в состоянии S, это нормально, потому что большинство программ почти всё время ждут событий. Тревожными могут быть другие картины: много процессов в R при нехватке ядер, длительно держащиеся D или накопившиеся Z. Как отличать нехватку процессора от ожидания диска, показывает страница про vmstat, а нагрузку в целом описывает страница про uptime и load average.
Процесс-зомби: что это и почему kill не помогает
Зомби это процесс, который уже завершился, но запись о нём осталась в таблице процессов. Дело в том, что после завершения процесс оставляет код возврата, и родитель должен его принять системным вызовом wait. Пока родитель этого не сделал, запись сохраняется, и в ps она отображается как Z, часто с пометкой defunct в столбце COMMAND.
Зомби не использует процессор и память программы, он занимает только одну запись в таблице, поэтому единичные зомби опасности не несут. Проблема возникает, когда их накапливаются тысячи: таблица процессов конечна.
Отправка сигналов зомби бесполезна, включая kill -9, потому что выполняться уже нечему, а убирать запись должен родитель. Что можно сделать:
- Найти родителя: ps -eo pid,ppid,stat,comm и посмотреть PPID у зомби.
- Попросить родителя принять завершение потомка. Некоторые программы реагируют на сигнал CHLD, но это зависит от конкретной программы, и сначала стоит изучить её документацию.
- Корректно перезапустить родительскую программу. Когда родитель завершается, зомби переходят к системному процессу init (в современных системах это его аналог или специальный процесс-«усыновитель»), который их принимает, и записи исчезают.
- Сообщить об ошибке разработчикам программы, если зомби появляются регулярно.
Состояние D: процесс «завис» и не убивается
Процесс в состоянии D (в macOS U) находится в непрерываемом ожидании. Обычно он ждёт завершения операции ввода-вывода: ответа диска, сетевой файловой системы, USB-устройства. Пока операция не завершится, сигналы к такому процессу не доставляются, и даже kill -9 откладывается до выхода из ожидания. Поэтому пользователь видит процесс, который не реагирует на завершение.
Короткие пребывания в D нормальны, на мгновение их видят почти все. Поводом для проверки служат процессы, которые остаются в D долго и в большом количестве. В Linux такие процессы увеличивают load average, о чём пишет страница про uptime, хотя процессор при этом может быть свободен.
Что проверить:
- iostat -x 1: нет ли очень длинных задержек на одном из устройств.
- dmesg: нет ли ошибок накопителя или потери связи с сетевым хранилищем.
- lsof -p PID: с какими файлами работает процесс; если среди них сетевой каталог, причина может быть там.
- Доступность сетевого ресурса, если процесс обращается к нему.
Решение лежит на уровне причины: восстановить доступ к устройству или хранилищу, после чего ожидание закончится само. Принудительное вытаскивание носителя или резкая перезагрузка потенциально ведёт к потере данных, поэтому к ним прибегают в последнюю очередь.
Как собрать список проблемных процессов
Чтобы быстро найти зомби и процессы в ожидании, достаточно одной команды и фильтра. Пример для обеих систем: ps -eo pid,ppid,stat,comm | awk '$3 ~ /^[DZU]/'. Здесь awk проверяет третий столбец, то есть STAT, и оставляет строки, где он начинается с D, Z или U. Заголовок при этом пропадает, если не начинается с этих букв: слово STAT начинается с S, поэтому оно не попадёт в результат. Подробнее о работе awk с столбцами написано на странице про awk '{print $1}'.
Повторите команду через несколько секунд, например через watch, и сравните. Если те же PID остаются, значит, ожидание длительное. Если номера меняются, это обычные короткие операции.
Для отчёта в поддержку или коллегам сохраните три вещи: вывод ps -eo pid,ppid,stat,etime,comm для проблемных процессов, фрагмент dmesg и данные iostat за тот же период. Это экономит время обмена вопросами и ответами.
Помните границы: состояние процесса не объясняет причину само по себе, оно только указывает направление поиска. Подробнее о завершении обычных процессов читайте на странице kill и top, а о выборе процесса по имени на странице про pgrep.
Короткое резюме по состояниям
Чтобы быстро ориентироваться в выводе, запомните несколько правил.
- R и S это нормальная работа и нормальное ожидание.
- Z это запись о завершённом процессе, лечится на стороне родителя.
- D и U указывают на ожидание ввода-вывода, причину ищут в устройстве или хранилище.
- T означает остановку: процесс можно продолжить, например сигналом CONT, если его остановили вручную.
- Дополнительные символы после буквы уточняют детали и не всегда сигнализируют о проблеме.
Решения принимайте по картине в целом: состояние процесса вместе с нагрузкой, памятью и сообщениями ядра, а не по одной букве.