Перейти к содержанию

09. Процессы

Введение

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

Администратор должен понимать:

  • что такое процесс и как он создаётся;
  • чем отличаются PID и PPID;
  • какие состояния могут иметь процессы;
  • что такое демоны и зомби-процессы;
  • как работают приоритеты и планировщик процессов;
  • какие данные о процессах хранит система.

Что такое процесс

Процесс — это выполняющаяся программа вместе со всеми данными и ресурсами, которые ей выделило ядро операционной системы. Когда пользователь или система запускает программу, ядро создаёт новый процесс и присваивает ему уникальный идентификатор (PID).

Каждый процесс в Linux существует как самостоятельная единица, которой выделены:

1. Основные компоненты процесса

  • Код программы (text segment) — машинные инструкции, выполняемые процессором.
  • Данные процесса (data segment) — переменные, структуры данных, статические данные.
  • Стек (stack) — область памяти для локальных переменных и вызовов функций.
  • Куча (heap) — динамически выделяемая память.
  • Открытые файловые дескрипторы — файлы, сокеты, устройства.
  • Переменные окружения — настройки запуска.
  • Таблица ресурсов — всё, что процесс использует: память, время CPU, порты.

2. Индивидуальные характеристики процесса

Каждый процесс имеет:

  • PID — уникальный номер процесса.
  • PPID — идентификатор родительского процесса.
  • UID/GID — пользователя и его группу, под которыми работает процесс.
  • Приоритет и значение nice — определяют порядок выполнения.
  • Состояние — текущее состояние цикла выполнения.
  • Командную строку запуска — что именно было запущено.

3. Процесс как контейнер ресурсов

Процесс не просто выполняет код — он является контейнером ресурсов.

К примеру, один процесс может иметь:

  • подключение к сети,
  • доступ к файлу,
  • активное использование процессора,
  • взаимодействие с другими процессами.

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

4. Жизненный цикл процесса

Процесс проходит несколько стадий:

  1. Создание (fork) — появляется копия родительского процесса.
  2. Инициализация (exec) — загружается реальная программа.
  3. Выполнение — процесс выполняет инструкции.
  4. Ожидание (sleep) — процесс временно не активен (например, ждёт данных).
  5. Завершение (exit) — процесс заканчивает работу.
  6. Ожидание удаления (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) создаются через последовательность:

  1. fork() — создание копии процесса
  2. exec() — загрузка новой программы в созданный процесс

Эта модель обеспечивает простоту, безопасность и независимость процессов.

Что происходит при вызове fork()

Когда вызывается fork(), ядро создаёт копию текущего процесса:

  • копируется память (виртуальное адресное пространство);
  • копируются файловые дескрипторы;
  • копируются переменные окружения;
  • создаётся новый PID.

Однако копирование происходит по механизму:

Что делает exec()

После создания копии процесса, он заменяет своё содержимое новым программным кодом с помощью exec().

exec():

  • загружает новую программу в процесс;
  • очищает память (код, стек, данные);
  • сохраняет PID;
  • запускает выполнение нового кода с первой инструкции.

Именно так работают все команды в терминале.

Пример в реальной жизни:

  • bash → fork → создаётся копия bash;
  • копия bash → exec → запускается команда ls.

Создание процессов демонами и службами

Службы, работающие через systemd, создают процессы иначе:

  • systemd запускает бинарный файл напрямую;
  • создаёт дочерний процесс, который не связан с терминалом;
  • процесс проходит процедуру демонизации (отсоединение от TTY);
  • systemd отслеживает работу процесса и перезапускает его при сбоях.

Для демонов fork() может вызываться дважды («двойной fork»), чтобы окончательно отвязаться от родителя.

Жизненный цикл процесса

  1. Создание — через fork()
  2. Замена содержимого — через exec()
  3. Назначение приоритета — планировщиком (CFS)
  4. Работа — процесс выполняет инструкции или спит (ожидание I/O)
  5. Завершениеexit()
  6. Ожидание удаления — состояние zombie
  7. Очистка — родитель получает статус через 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 и роль планировщика.