Выход из программы осуществляется с помощью системного вызова exit()
. Эта функция завершает процесс и освобождает все занятые им ресурсы. Родительский процесс может запросить о состоянии порожденных им процессов с помощью системного вызова wait4()
[9], который заставляет один процесс ожидать завершения другого. Когда процесс завершается, он переходит в специальное состояние wait()
или waitpid()
.
Иное название для процесса —
Дескриптор процесса и структура task structure
Ядро хранит информацию о всех процессах в двухсвязном списке, который называется struct task_struct
, которая описана в файле include/linux/sched.h
. Дескриптор процесса содержит всю информацию об определенном процессе.
Структура task_struct
— достаточно большая структура данных размером порядка 1,7 Кбайт на 32-разрядной машине. Однако этот размер не такой уж большой, учитывая, что в данной структуре содержится вся информация о процессе, которая необходима ядру. Дескриптор процесса содержит данные, которые описывают выполняющуюся программу, — открытые файлы, адресное пространство процесса, ожидающие на обработку сигналы, состояние процесса и многое другое (рис. 3.1).
Рис. 3.1. Дескриптор процесса и список задач
Выделение дескриптора процесса
Память для структуры task_struct
выделяется с помощью подсистемы выделения памяти, которая называется task_struct
хранилась в конце стека ядра каждого процесса. Это позволяет для аппаратных платформ, у которых достаточно мало регистров процессора (как, например, платформа x86), вычислять местоположение дескриптора процесса, только зная значение регистра thread_info
, которая хранится в области дна стека (для платформ, у которых стек растет в сторону уменьшения значения адреса памяти) или в области вершины стека (для платформ, у которых стек растет в сторону увеличения значения адреса памяти)[11] (рис. 3.2.).
Рис 3.2. Дескриптор процесса и стек ядра
Структура struct thread_info
для платформы x86 определена в файле
в следующем виде.
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
unsigned long flags;
unsigned long status;
__u32 cpu;
__s32 preempt_count;
mm_segment_t addr_limit;
struct restart_block restart_block;
unsigned long previous_esp;
__u8 supervisor_stack[0];
};
Для каждой задачи ее структура thread_info
хранится в конце стека ядра этой задачи. Элемент структуры thread_info
с именем task
является указателем на структуру task_struct
этой задачи.
Хранение дескриптора процесса
Система идентифицирует процессы с помощью уникального значения, которое называется PID
— это целое число, представленное с помощью скрытого типа pid_t
[12] , который обычно соответствует знаковому целому— int
.
Однако, для обратной совместимости со старыми версиями ОС Unix и Linux максимальное значение этого параметра по умолчанию составляет всего лишь 32768 (что соответствует типу данных short int
). Ядро хранит значение данного параметра в поле pid
дескриптора процесса.