Процесс, его контекст и состояния

⏱ 25 мин · 🧩 заданий: 5

Программа и процесс

Программа — файл на диске: машинный код и данные. Процесс — программа в момент выполнения вместе со всем, что ей нужно: адресное пространство, значения регистров, открытые файлы, состояние.

Одну программу могут выполнять несколько процессов одновременно (десять терминалов с bash — десять процессов одной программы).

Процесс — единица, которой ОС выделяет ресурсы: память, файлы, процессорное время. Ядро описывает каждый процесс структурой-дескриптором (PCB, Process Control Block), в Linux это struct task_struct.

Контекст процесса

Всё, что нужно, чтобы остановить процесс и потом продолжить с того же места:

Часть Что входит
Пользовательский контекст код, данные, стек, куча, разделяемые библиотеки — содержимое адресного пространства
Регистровый контекст счётчик команд, указатель стека, регистры общего назначения, флаги
Системный контекст то, что ядро хранит о процессе: PID, PPID, UID, состояние, приоритет, таблицы страниц, таблица файловых дескрипторов, обработчики и маски сигналов, текущий каталог, лимиты, стек ядра

При переключении процессов ядро сохраняет регистровый контекст в системной части, а пользовательский остаётся в памяти (меняется лишь cr3 — какой адресное пространство видит процессор).

task_struct (упрощённо)

struct task_struct {
    volatile long         state;      /* TASK_RUNNING, TASK_INTERRUPTIBLE, ... */
    pid_t                 pid;        /* идентификатор потока */
    pid_t                 tgid;       /* идентификатор группы потоков = PID процесса */
    struct task_struct   *real_parent;/* родитель */
    struct list_head      children;   /* список потомков */
    struct mm_struct     *mm;         /* адресное пространство: VMA, таблицы страниц (pgd) */
    struct files_struct  *files;      /* таблица открытых файлов */
    struct fs_struct     *fs;         /* корень и текущий каталог */
    struct signal_struct *signal;     /* общие сигнальные данные, сеанс, группа */
    struct sighand_struct*sighand;    /* обработчики сигналов */
    sigset_t              blocked;    /* маска блокированных сигналов */
    struct sigpending     pending;    /* ожидающие сигналы */
    const struct cred    *cred;       /* uid, gid, права */
    int                   prio;       /* приоритет */
    /* ... ещё сотни полей ... */
};

Идентификаторы

#include <unistd.h>

pid_t me     = getpid();    /* свой PID */
pid_t parent = getppid();   /* PID родителя */

Каждый процесс (кроме самых первых, созданных ядром) имеет родителя. Процессы образуют дерево, корень пространства пользователя — init (PID 1).

ps -eo pid,ppid,stat,comm | head
pstree -p

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

fork │ ▼ планировщик выбрал ┌──────────▶ ГОТОВ ─────────────────────▶ ВЫПОЛНЯЕТСЯ ──── exit ───▶ ЗОМБИ │ (runnable) ◀─────────────────── (running) │ │ истёк квант / │ wait родителя ▼ │ вытеснение │ удалён │ событие произошло ждёт событие │ │ (ввод готов, сигнал) (read, sleep) │ └────────────── ОЖИДАЕТ ◀───────────────────────────┘ (sleeping) SIGSTOP/SIGTSTP/SIGTTIN ВЫПОЛНЯЕТСЯ/ГОТОВ ──────────────────────────▶ ОСТАНОВЛЕН ◀────────── SIGCONT ─────── (stopped)
Состояние В Linux В ps
Выполняется / готов TASK_RUNNING R
Ожидает (прерываемо сигналом) TASK_INTERRUPTIBLE S
Ожидает (непрерываемо, обычно диск) TASK_UNINTERRUPTIBLE D
Остановлен TASK_STOPPED T
Зомби EXIT_ZOMBIE Z

Обратите внимание

Из ожидания процесс никогда не переходит сразу к выполнению: сначала становится готовым и ждёт, пока планировщик выберет его. Linux не различает «готов» и «выполняется» в поле состояния — оба TASK_RUNNING.

Остановленное состояние и сигналы

Состояние «остановлен» связано с сигналами: SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU по умолчанию останавливают процесс (не завершая его), а SIGCONT продолжает. Это столбец «останавливает процесс» в таблице задачи 1.

Итог

  • Процесс — выполняющийся экземпляр программы; ядро описывает его дескриптором (task_struct).
  • Контекст: пользовательский (память), регистровый, системный (данные ядра о процессе).
  • Состояния: готов, выполняется, ожидает, остановлен, зомби.
  • Процессы образуют дерево с корнем init (PID 1).

Практика решено 0 из 5

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Один вариант ответа

Чем процесс отличается от программы?

Задание 2 Заполнить таблицу

Отнесите элементы к частям контекста процесса.

Пользовательский контекстРегистровый контекстСистемный контекст (в ядре)
Код и данные программы, стек, куча
Счётчик команд (rip) и указатель стека
Таблица открытых файловых дескрипторов
Обработчики сигналов и маска сигналов
Таблицы страниц процесса
Регистры общего назначения (rax, rbx...)
PID, PPID, идентификаторы пользователя
Отметьте ячейку — «+», пустая — «−».
Задание 3 Расставить по порядку

Процесс читает с клавиатуры. Расставьте его состояния по порядку:

  1. Выполняется (running): вызывает read(0, ...)
  2. Выполняется (running): планировщик выбрал процесс, read возвращает данные
  3. Ожидает (sleeping): данных нет, ядро усыпляет процесс до нажатия клавиши
  4. Готов (ready/runnable): пришло прерывание клавиатуры, ядро разбудило процесс и поставило в очередь
Задание 4 Ввод ответа

Как в выводе ps обозначается состояние процесса-зомби? (одна буква)

Задание 5 Несколько вариантов

Какие переходы между состояниями возможны?

Войдите, чтобы отмечать пройденные уроки.