Выполнение процесса может происходить в двух режимах — в режиме ядра (kernel mode) или в режиме задачи (user mode). В режиме задачи процесс выполняет инструкции прикладной программы, допустимые на непривилегированном уровне защиты процессора. При этом процессу недоступны системные структуры данных. Когда процессу требуется получение каких- либо услуг ядра, он делает системный вызов, который выполняет инструкции ядра, находящиеся на привилегированном уровне. Несмотря на то что выполняются инструкции ядра, это происходит от имени процесса, сделавшего системный вызов. Выполнение процесса при этом переходит в режим ядра. Таким образом ядро системы защищает собственное адресное пространство от доступа прикладного процесса, который может нарушить целостность структур данных ядра и привести к разрушению операционной системы. Более того, часть процессорных инструкций, например, изменение регистров, связанных с управлением памятью, могут быть выполнены только в режиме ядра.
Соответственно и образ процесса состоит из двух частей: данных режима ядра и режима задачи. Образ процесса в режиме задачи состоит из сегмента кода, данных, стека, библиотек и других структур данных, к которым он может получить непосредственный доступ. Образ процесса в режиме ядра состоит из структур данных, недоступных процессу в режиме задачи, которые используются ядром для управления процессом. Сюда относятся данные, диктуемые аппаратным уровнем, например состояния регистров, таблицы для отображения памяти и т.д., а также структуры данных, необходимые ядру для обслуживания процесса. Вообще говоря, в режиме ядра процесс имеет доступ к любой области памяти.
Структуры данных процесса
Каждый процесс представлен в системе двумя основными структурами данных — proc и user, описанными, соответственно, в файлах и . Содержимое и формат этих структур различны для разных версий UNIX. В табл. 3.1 приведены некоторые поля структуры proc
в SCO UNIX, позволяющие проиллюстрировать информацию, необходимую ядру, для управления процессом.
Таблица 3.1. Структура proc
char |
p_stat |
Состояние процесса (выполнение, приостановлен, сон и т.д.) |
char |
p_pri |
Текущий приоритет процесса |
unsigned int |
p_flag |
Флаги, определяющие дополнительную информацию о состоянии процесса |
unsigned short |
p_uid |
UID процесса |
unsigned short |
p_suid |
EUID процесса |
int |
p_sid |
Идентификатор сеанса |
short |
p_pgrp |
Идентификатор группы процессов (равен идентификатору лидера группы) |
short |
p_pid |
Идентификатор процесса (PID) |
short |
p_ppid |
Идентификатор родительского процесса (PPID) |
sigset_t |
p_sig |
Сигналы, ожидающие доставки |
unsigned int |
p_size |
Размер адресного пространства процесса в страницах |
time_t |
p_utime |
Время выполнения в режиме задачи |
time_t |
p_stime |
Время выполнения в режиме ядра |
caddr_t |
p_ldt |
Указатель на LDT процесса |
struct pregion |
*p_region |
Список областей памяти процесса |
short |
p_xstat |
Код возврата, передаваемый родительскому процессу |
unsigned int |
p_utbl[] |
Массив записей таблицы страниц для u-area |
В любой момент времени данные структур proc
для всех процессов должны присутствовать в памяти, хотя остальные структуры данных, включая образ процесса, могут быть перемещены во вторичную память, — область свопинга. Это позволяет ядру иметь под рукой минимальную информацию, необходимую для определения местонахождения остальных данных, относящихся к процессу, даже если они отсутствуют в памяти.
Структура proc
является записью системной таблицы процессов, которая, как мы только что заметили, всегда находится в оперативной памяти. Запись этой таблицы для выполняющегося в настоящий момент времени процесса адресуется системной переменной curproc
. Каждый раз при переключении контекста, когда ресурсы процессора передаются другому процессу, соответственно изменяется значение переменной curproc
, которая теперь указывает на структуру proc
активного процесса.
Вторая упомянутая структура — user
, также называемая u-area или u-block, содержит дополнительные данные о процессе, которые требуются ядру только во время выполнения процесса (т.е. когда процессор выполняет инструкции процесса в режиме ядра или задачи). В отличие от структуры proc
, адресованной указателем curproc
, данные user
размещаются (точнее, отображаются) в определенном месте виртуальной памяти ядра и адресуются переменной u
. На рис. 3.2 показаны две основные структуры данных процесса и способы их адресации ядром UNIX.
Читать дальше