Разработка ядра Linux | страница 34
С этого момента говорят, что ядро "выполняется от имени процесса" и делает это в контексте процесса. В контексте процесса макрос >current
является действительным[14]. При выходе из режима ядра процесс продолжает выполнение в пространстве пользователя, если в это время не появляется готовый к выполнению более приоритетный процесс. В таком случае активизируется планировщик, который выбирает для выполнения более приоритетный процесс.
Системные вызовы и обработчики исключительных ситуаций являются строго определенными интерфейсами ядра. Процесс может начать выполнение в пространстве ядра только посредством одного из этих интерфейсов — любые обращения к ядру возможны только через эти интерфейсы.
Дерево семейства процессов
В операционной системе Linux существует четкая иерархия процессов. Все процессы являются потомками процесса >init
, значение идентификатора >PID
для которого равно 1. Ядро запускает процесс >init
на последнем шаге процедуры загрузки системы. Процесс >init
, в свою очередь, читает системные файлы сценариев начальной загрузки (initscripts) и выполняет другие программы, что в конце концов завершает процедуру загрузки системы.
Каждый процесс в системе имеет всего один порождающий процесс. Кроме того, каждый процесс может иметь один или более порожденных процессов. Процессы, которые порождены одним и тем же родительским процессом, называются родственными (siblings). Информация о взаимосвязи между процессами хранится в дескрипторе процесса. Каждая структура >task_struct
содержит указатель на структуру >task_struct
родительского процесса, который называется parent, эта структура также имеет список порожденных процессов, который называется >children
. Следовательно, если известен текущий процесс (>current
), то для него можно определить дескриптор родительского процесса с помощью выражения:
>struct task_struct *task = current->parent;
Аналогично можно выполнить цикл по процессам, порожденным от текущего процесса, с помощью кода:
>struct task_struct *task;
>struct list_head *list;
>list_for_each(list, ¤t->children) {
> task = list_entry(list, struct task_struct, sibling);
> /* переменная task теперь указывает на один из процессов,
> порожденных текущим процессом */
>}
Дескриптор процесса >init
— это статически выделенная структура данных с именем >init_task
. Хороший пример использования связей между всеми процессами — это приведенный ниже код, который всегда выполняется успешно.
>struct task_struct *task;