Разработка ядра Linux | страница 31



Рис. 3.1. Дескриптор процесса и список задач

Выделение дескриптора процесса

Память для структуры >task_struct выделяется с помощью подсистемы выделения памяти, которая называется слябовый распределитель (slab allocator), для возможности повторного использования объектов и раскрашивания кэша (cache coloring) (см. главу 11, "Управление памятью"). В ядрах до серии 2.6 структура >task_struct хранилась в конце стека ядра каждого процесса. Это позволяет для аппаратных платформ, у которых достаточно мало регистров процессора (как, например, платформа x86), вычислять местоположение дескриптора процесса, только зная значение регистра указателя стека (stack pointer), без использования дополнительных регистров для хранения самого адреса этого местоположения. Так как теперь дескриптор процесса создается с помощью слябового распределителя, была введена новая структура >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 этой задачи.

Хранение дескриптора процесса

Система идентифицирует процессы с помощью уникального значения, которое называется идентификатором процесса (process identification, PID). Идентификатор >PID — это целое число, представленное с помощью скрытого типа >pid_t[12] , который обычно соответствует знаковому целому— >int.

Однако, для обратной совместимости со старыми версиями ОС Unix и Linux максимальное значение этого параметра по умолчанию составляет всего лишь 32768 (что соответствует типу данных >short int). Ядро хранит значение данного параметра в поле >pid дескриптора процесса.

Это максимальное значение является важным, потому что оно определяет максимальное количество процессов, которые одновременно могут существовать в системе. Хотя значения 32768 и достаточно для офисного компьютера, для больших серверов может потребоваться значительно больше процессов. Чем меньше это значение, тем скорее нумерация процессов будет начинаться сначала, что приводит к нарушению полезного свойства: больший номер процесса соответствует процессу, который запустился позже. Если есть желание нарушить в системе обратную совместимость со старыми приложениями, то администратор может увеличить это максимальное значение во время работы системы с помощью записи его в файл