09. Процессы
Введение
Процессы — ключевая часть работы операционной системы Linux. Каждый процесс представляет собой запущенную программу, которой ядро выделяет процессорное время, память и другие ресурсы. Linux — многозадачная и многопользовательская ОС, поэтому управление процессами является важной частью системного администрирования.
Администратор должен понимать:
- что такое процесс и как он создаётся;
- чем отличаются PID и PPID;
- какие состояния могут иметь процессы;
- что такое демоны и зомби-процессы;
- как работают приоритеты и планировщик процессов;
- какие данные о процессах хранит система.
Что такое процесс
Процесс — это выполняющаяся программа вместе со всеми данными и ресурсами, которые ей выделило ядро операционной системы. Когда пользователь или система запускает программу, ядро создаёт новый процесс и присваивает ему уникальный идентификатор (PID).
Каждый процесс в Linux существует как самостоятельная единица, которой выделены:
1. Основные компоненты процесса
- Код программы (text segment) — машинные инструкции, выполняемые процессором.
- Данные процесса (data segment) — переменные, структуры данных, статические данные.
- Стек (stack) — область памяти для локальных переменных и вызовов функций.
- Куча (heap) — динамически выделяемая память.
- Открытые файловые дескрипторы — файлы, сокеты, устройства.
- Переменные окружения — настройки запуска.
- Таблица ресурсов — всё, что процесс использует: память, время CPU, порты.
2. Индивидуальные характеристики процесса
Каждый процесс имеет:
- PID — уникальный номер процесса.
- PPID — идентификатор родительского процесса.
- UID/GID — пользователя и его группу, под которыми работает процесс.
- Приоритет и значение nice — определяют порядок выполнения.
- Состояние — текущее состояние цикла выполнения.
- Командную строку запуска — что именно было запущено.
3. Процесс как контейнер ресурсов
Процесс не просто выполняет код — он является контейнером ресурсов.
К примеру, один процесс может иметь:
- подключение к сети,
- доступ к файлу,
- активное использование процессора,
- взаимодействие с другими процессами.
Все эти данные изолированы друг от друга, что обеспечивает безопасность и стабильность системы: один процесс не может напрямую вмешиваться в память другого.
4. Жизненный цикл процесса
Процесс проходит несколько стадий:
- Создание (fork) — появляется копия родительского процесса.
- Инициализация (exec) — загружается реальная программа.
- Выполнение — процесс выполняет инструкции.
- Ожидание (sleep) — процесс временно не активен (например, ждёт данных).
- Завершение (exit) — процесс заканчивает работу.
- Ожидание удаления (zombie) — краткая стадия, пока родитель не забрал статус.
5. Важность процессов в Linux
Процессы обеспечивают:
- многозадачность (несколько программ одновременно),
- многопользовательскую работу,
- гибкое управление ресурсами,
- распределение нагрузки,
- стабильность системы благодаря изоляции.
Linux строится вокруг модели процессов, поэтому понимание их структуры — фундаментальное знание для администратора.
PID и PPID
Каждый процесс имеет:
- PID (Process ID) — уникальный идентификатор процесса;
- PPID (Parent Process ID) — идентификатор родительского процесса.
Все процессы происходят от процесса systemd (PID 1), который запускает систему и другие службы.
Пример просмотра PID и PPID:
ps -o pid,ppid,cmd
Как создаются процессы
Создание процессов в Linux основано на двух фундаментальных механизмах: fork() и exec(). Эти два системных вызова лежат в основе многозадачности Unix-подобных систем. Понимание их работы — ключевой навык системного администратора.
Модель fork/exec: основа работы процессов в Linux
Все процессы в Linux (кроме systemd) создаются через последовательность:
fork()— создание копии процессаexec()— загрузка новой программы в созданный процесс
Эта модель обеспечивает простоту, безопасность и независимость процессов.
Что происходит при вызове fork()
Когда вызывается fork(), ядро создаёт копию текущего процесса:
- копируется память (виртуальное адресное пространство);
- копируются файловые дескрипторы;
- копируются переменные окружения;
- создаётся новый PID.
Однако копирование происходит по механизму:
Что делает exec()
После создания копии процесса, он заменяет своё содержимое новым программным кодом с помощью exec().
exec():
- загружает новую программу в процесс;
- очищает память (код, стек, данные);
- сохраняет PID;
- запускает выполнение нового кода с первой инструкции.
Именно так работают все команды в терминале.
Пример в реальной жизни:
- bash → fork → создаётся копия bash;
- копия bash → exec → запускается команда
ls.
Создание процессов демонами и службами
Службы, работающие через systemd, создают процессы иначе:
- systemd запускает бинарный файл напрямую;
- создаёт дочерний процесс, который не связан с терминалом;
- процесс проходит процедуру демонизации (отсоединение от TTY);
- systemd отслеживает работу процесса и перезапускает его при сбоях.
Для демонов fork() может вызываться дважды («двойной fork»), чтобы окончательно отвязаться от родителя.
Жизненный цикл процесса
- Создание — через
fork() - Замена содержимого — через
exec() - Назначение приоритета — планировщиком (CFS)
- Работа — процесс выполняет инструкции или спит (ожидание I/O)
- Завершение —
exit() - Ожидание удаления — состояние zombie
- Очистка — родитель получает статус через
wait()
Связь процессов между собой
Процессы могут наследовать от родителя:
- переменные окружения;
- рабочую директорию;
- файловые дескрипторы;
- права доступа.
Но дальнейшее выполнение полностью изолировано, что делает Linux стабильным и многопользовательским.
Состояния процессов
Процессы могут иметь различные состояния, которые отображаются в ps/top.
| Состояние | Обозначение | Описание |
|---|---|---|
| Running | R | Выполняется или готов к выполнению |
| Sleeping | S | Ожидает события (самое частое состояние) |
| Uninterruptible sleep | D | Ожидание I/O, не прерывается сигналами |
| Stopped | T | Остановлен (Ctrl+Z или сигналом) |
| Zombie | Z | Завершён, но родитель не забрал статус |
| Idle | I | Потоки ядра без активности |
Состояния процессов
Процессы в Linux могут находиться в различных состояниях. Эти состояния помогают понимать, чем занят процесс и почему он ведёт себя определённым образом. Состояния отображаются в таких инструментах, как ps, top, htop.
Running (R) — выполняется или готов к выполнению
Это одно из основных состояний процесса.
- Процесс выполняет инструкции процессора прямо сейчас, или находится в очереди выполнения.
- Процессор переключается между несколькими процессами в течение миллисекунд, поэтому даже короткие задачи часто отмечаются как «Running».
- Обычно таких процессов немного — только те, что активно используют CPU.
Пример просмотра процессов в состоянии R:
ps -eo pid,state,cmd | grep ' R '
Sleeping (S) — ожидает событие
Это самое распространённое состояние процессов в Linux.
- Процесс не выполняется, потому что ждёт событие: ввод данных, завершение операции, сигнал, сетевой ответ.
- Как только событие произойдёт, планировщик вернёт процесс в очередь выполнения.
- Большинство программ проводят 90% времени именно в этом состоянии.
Состояние S — это обычный, нормальный сон, из которого процесс легко «разбудить».
Uninterruptible sleep (D) — ожидание ввода-вывода
Это состояние часто вызывает интерес, потому что:
- процесс находится в глубокой паузе и не может быть прерван сигналами (в том числе
kill -9); - обычно процесс ждёт аппаратный ввод-вывод: ответ диска, сети, USB-устройства;
- если таких процессов много, это признак проблем с диском или драйвером.
Состояние D может означать:
- зависание дисковой системы,
- ошибку файловой системы,
- медленный или неисправный HDD/SSD,
- перегрузку I/O.
Это опасное состояние, требующее диагностики.
Stopped (T) — остановлен
Процесс приостановлен и не выполняет инструкции. Причины:
- пользователь нажал Ctrl + Z;
- процесс остановлен сигналом
SIGSTOPилиSIGTSTP; - процесс ожидает возобновления (
SIGCONT).
Обычные сценарии:
- пользователь временно останавливает программу, чтобы вернуть её командой
bgилиfg.
Zombie (Z) — зомби-процесс
Зомби-процесс — это завершённый процесс, который ещё не удалён из таблицы процессов.
Причины:
- процесс завершился вызовом
exit(); - родитель должен выполнить
wait()и забрать статус завершения; - если родитель не делает этого, процесс остаётся в состоянии Z.
Особенности:
- зомби не используют CPU или память, но занимают запись в таблице процессов;
- если таких процессов становится много, таблица может заполниться — это критическая ситуация.
Обычно зомби появляются из-за ошибок в программах.
Idle (I) — бездействующие процессы ядра
Используется для потоков ядра, которые ничего не делают:
- это внутренние процессы, которые работают на уровне ОС;
- такие процессы не относятся к обычным пользовательским программам;
- в инструментах мониторинга помечаются как
I.
Процессы ядра не отображаются как обычные процессы и не завершаются пользователем.
Дополнительные состояния (в редких случаях)
Некоторые утилиты отображают и другие варианты:
- X — мёртвый процесс (dead). Его уже удаляют.
- K — ядро завершило процесс, но он ещё видим.
- P — процесс в режиме ожидания страниц (paging). Сейчас почти не встречается.
- L — процесс заблокировал страницу памяти.
- s — лидер сессии.
- + — процесс принадлежит группе foreground.
Демоны (daemon)
Демон (daemon) — это особый тип процесса в Linux, который выполняется в фоновом режиме, не имея привязки к терминалу или пользователю. Демоны обеспечивают работу ключевых сервисов системы: сетевых служб, планировщиков задач, журналов, веб-серверов, драйверов и многого другого.
Название daemon происходит из мифологии и означает «дух-помощник», что точно описывает их роль — незаметно обеспечивать работу системы.
Основные признаки демона
Демоны отличаются от обычных процессов несколькими важными характеристиками:
- Работают в фоне, без взаимодействия с пользователем.
- Запускаются автоматически при старте системы (через systemd).
- Не имеют управляющего терминала (TTY = none).
- Имеют PPID = 1, то есть их родителем становится процесс
systemd. - Работают длительное время, пока система включена.
- Обрабатывают системные задачи, часто связанные с сетью, вводом-выводом или обслуживанием.
Примеры демонов в Linux
Вот наиболее распространённые демоны:
| Демон | Назначение |
|---|---|
| sshd | Обеспечивает удалённый доступ по SSH |
| cron | Выполнение задач по расписанию |
| systemd-journald | Сбор и хранение системных логов |
| NetworkManager | Управление сетевыми настройками |
| cupsd | Поддержка печати |
| nginx, apache2 | Веб-серверы |
| mysqld, postgresql | Сервисы баз данных |
| bluetoothd | Bluetooth-службы |
Проверка работы демона
Проверить запущен ли демон можно несколькими способами:
Через ps:
ps -ef | grep sshd
Через systemd:
systemctl status sshd
Посмотреть все демоны, запущенные systemd:
systemctl --type=service
Зачем нужны демоны
Демоны обеспечивают:
- работу сетевого стека;
- запуск, мониторинг и журналирование системных процессов;
- доступ к сети, БД, серверам приложений;
- безопасность и аутентификацию (например,
sshd); - системные службы, от которых зависит нормальная работа ОС.
Без демонов Linux просто не сможет функционировать как полноценная операционная система.
Приоритеты процессов (nice и renice)
Каждый процесс имеет приоритет выполнения.
Значение nice:
- диапазон от 20 (максимальный приоритет) до +19 (минимальный);
- обычные пользователи могут только понижать приоритет (увеличивать nice);
- root может назначать любые значения.
Просмотр приоритета:
ps -o pid,ni,cmd
Запуск процесса с приоритетом:
nice -n 10 команда
Изменение приоритета:
renice -n -5 1234
Заключение
Процессы — основа многозадачности Linux, и понимание их работы является одним из ключевых навыков администратора. В этой лекции рассмотрено устройство процесса, его жизненный цикл, состояния, приоритеты, работу демонов и зомби, а также каталог /proc и роль планировщика.