Модель процесса — это способ, которым ядро Linux представляет, изолирует и управляет выполнением программ.

Процесс в Linux — это не просто запущенная программа, а совокупность:

  • исполняемого кода
  • контекста выполнения
  • выделенных ресурсов
  • метаданных, которыми оперирует ядро

Основные понятия

Дескриптор процесса (task_struct)
Основная структура ядра, описывающая процесс. Содержит:

  • PID (идентификатор процесса)
  • состояние (running, sleeping и т.д.)
  • параметры планирования (приоритет, policy)
  • ссылки на память (mm_struct)
  • файловые дескрипторы (files_struct)
  • информацию о сигналах

Фактически, task_struct — это точка входа ядра ко всем аспектам процесса.

Контекст выполнения (execution context)
Набор данных, необходимых для продолжения выполнения:

  • регистры CPU
  • указатель стека
  • счётчик команд
    Сохраняется и восстанавливается при переключении задач (context switch).

Виртуальное адресное пространство
Каждый процесс изолирован и работает в собственной памяти:

  • text (код)
  • data / bss
  • heap
  • stack
    Изоляция обеспечивается MMU и таблицами страниц.

Файловые дескрипторы (file descriptors)
Унифицированный интерфейс доступа к ресурсам:

  • файлы
  • сокеты
  • пайпы
    Стандартные:
  • 0 — stdin
  • 1 — stdout
  • 2 — stderr

Состояния процесса

  • Running — выполняется или готов к выполнению
  • Interruptible sleep — ожидает события (можно прервать сигналом)
  • Uninterruptible sleep — ожидает (обычно I/O), не прерывается
  • Stopped — остановлен (например, сигналом)
  • Zombie — завершён, но ещё не обработан родителем

Состояние отражает, участвует ли процесс в планировании.

Иерархия процессов Процессы образуют дерево:

  • у каждого есть родитель (PPID)
  • возможны потомки
    Корневой процесс — init/systemd.

Завершённые процессы остаются в состоянии zombie, пока родитель не считает их статус (wait()).

Создание процессов Классическая модель:

  • fork() — создаёт копию процесса
  • exec() — заменяет адресное пространство новой программой

Особенности:

  • используется copy-on-write (память не копируется сразу)
  • fork → exec — стандартный паттерн запуска программ

Потоки (threads)
В Linux нет жёсткого разделения на процессы и потоки.

Потоки реализованы через clone():

  • разделяют память
  • разделяют файловые дескрипторы
  • имеют общий PID namespace (в рамках thread group)

С точки зрения ядра — это те же task_struct, но с разными флагами.

Планирование Процесс — это планируемая единица CPU. Основное:

  • используется CFS (Completely Fair Scheduler)
  • учитываются приоритеты (nice)
  • каждому процессу выделяется «виртуальное время»

Планировщик работает с task’ами, а не абстрактными «процессами».

Сигналы (signals)
Механизм асинхронного взаимодействия:

  • уведомление процесса о событиях
  • управление (SIGTERM, SIGKILL, SIGSTOP)

Обрабатываются либо пользовательским кодом, либо по умолчанию ядром.

Изоляция и ограничения Дополнительные механизмы:

  • namespaces — изоляция (PID, mount, network и др.)
  • cgroups — контроль ресурсов (CPU, память, I/O)

Используются, например, в Docker.

Практический смысл

  • Процесс — базовая единица изоляции: память, дескрипторы, права.
  • Потоки — способ разделения ресурсов внутри процесса.
  • task_struct — ключ к пониманию того, как ядро «видит» выполнение.
  • fork/exec — фундаментальная модель запуска программ в Unix-системах.
  • Анализ процессов обычно ведётся через ps, top, htop, /proc.