Разработка ядра 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;