Операционная система UNIX
Шрифт:
Соответственно и образ процесса состоит из двух частей: данных режима ядра и режима задачи. Образ процесса в режиме задачи состоит из сегмента кода, данных, стека, библиотек и других структур данных, к которым он может получить непосредственный доступ. Образ процесса в режиме ядра состоит из структур данных, недоступных процессу в режиме задачи, которые используются ядром для управления процессом. Сюда относятся данные, диктуемые аппаратным уровнем, например состояния регистров, таблицы для отображения памяти и т.д., а также структуры данных, необходимые ядру для обслуживания процесса. Вообще говоря, в режиме ядра процесс имеет доступ к любой области памяти.
Структуры данных процесса
Каждый процесс представлен в системе двумя основными структурами данных — proc и user, описанными, соответственно, в файлах <sys/proc.h> и <sys/user.h>. Содержимое и формат этих структур различны для разных версий 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 |
В любой момент времени данные структур
Структура
Вторая упомянутая структура —
Рис. 3.2. Основные структуры данных процесса
В u-area хранятся данные, которые используются многими подсистемами ядра и не только для управления процессом. В частности, там содержится информация об открытых файловых дескрипторах, диспозиция сигналов, статистика выполнения процесса, а также сохраненные значения регистров, когда выполнение процесса приостановлено. Очевидно, что процесс не должен иметь возможности модифицировать эти данные произвольным образом, поэтому u-area защищена от доступа в режиме задачи.
Как видно из рис. 3.2, u-area также содержит стек фиксированного размера, — системный стек или стек ядра (kernel stack). При выполнении процесса в режиме ядра операционная система использует этот стек, а не обычный стек процесса.
Состояния процесса
Жизненный цикл процесса может быть разбит на несколько состояний. Переход процесса из одного состояния в другое происходит в зависимости от наступления тех или иных событий в системе. На рис. 3.3 показаны состояния, в которых процесс может находиться с момента создания до завершения выполнения.
1. Процесс выполняется в режиме задачи. При этом процессором выполняются прикладные инструкции данного процесса.
2. Процесс выполняется в режиме ядра. При этом процессором выполняются системные инструкции ядра операционной системы от имени процесса.
3. Процесс не выполняется, но готов к запуску, как только планировщик выберет его (состояние runnable). Процесс находится в очереди на выполнение и обладает всеми необходимыми ему ресурсами, кроме вычислительных.
4. Процесс находится в состоянии сна (asleep), ожидая недоступного в данный момент ресурса, например завершения операции ввода/вывода.
5. Процесс возвращается из режима ядра в режим задачи, но ядро прерывает его и производит переключение контекста для запуска более высокоприоритетного процесса.
6. Процесс только что создан вызовом fork(2) и находится в переходном состоянии: он существует, но не готов к запуску и не находится в состоянии сна.
7. Процесс выполнил системный вызов exit(2) и перешел в состояние зомби (zombie, defunct). Как такового процесса не существует, но остаются записи, содержащие код возврата и временную статистику его выполнения, доступную для родительского процесса. Это состояние является конечным в жизненном цикле процесса.
Рис. 3.3. Состояния процесса
Необходимо отметить, что не все процессы проходят через все множество состояний, приведенных выше.
Процесс начинает свой жизненный путь с состояния 6, когда родительский процесс выполняет системный вызов fork(2). После того как создание процесса полностью завершено, процесс завершает "дочернюю часть" вызова fork(2) и переходит в состояние 3 готовности к запуску, ожидая своей очереди на выполнение. Когда планировщик выбирает процесс для выполнения, он переходит в состояние 1 и выполняется в режиме задачи.
Выполнение в режиме задачи завершается в результате системного вызова или прерывания, и процесс переходит режим ядра, в котором выполняется код системного вызова или прерывания. После этого процесс опять может вернуться в режим задачи. Однако во время выполнения системного вызова в режиме ядра процессу может понадобиться недоступный в данный момент ресурс. Для ожидания доступа к такому ресурсу, процесс вызывает функцию ядра