Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

Каждый процесс в системе имеет всего один порождающий процесс. Кроме того, каждый процесс может иметь один или более порожденных процессов. Процессы, которые порождены одним и тем же родительским процессом, называются родственными (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, &current->children) {

 task = list_entry(list, struct task_struct, sibling);

 /* переменная task теперь указывает на один из процессов,

порожденных текущим процессом */

}

Дескриптор процесса

init
— это статически выделенная структура данных с именем
init_task
. Хороший пример использования связей между всеми процессами — это приведенный ниже код, который всегда выполняется успешно.

struct task_struct *task;

for (task = current; task != $init_task; task = task->parent)

 ;

/* переменная task теперь указывает на процесс init */

Конечно, проходя по иерархии процессов, можно перейти от одного процесса системы к другому. Иногда, однако, желательно выполнить цикл по всем процессам системы. Такая задача решается очень просто, так как список задач — это двухсвязный список. Для того чтобы получить указатель на следующее задание из этого списка, имея действительный указатель на дескриптор какого-либо процесса, можно использовать показанный ниже код:

list_entry(task->tasks.next, struct task_struct, tasks);

Получение указателя на предыдущее задание работает аналогично.

list_entry(task->tasks.prev, struct task_struct, tasks);

Дна указанных выше выражения доступны также в виде макросов

next_task(task)
(получить следующую задачу),
prev_task(task)
(получить предыдущую задачу). Наконец, макрос
for_each_process(task)
позволяет выполнить цикл по всему списку задач. На каждом шаге цикла переменная
task
указывает на следующую задачу из списка:

struct task_struct *task;

for_each_process(task) {

 /* просто печатается имя команды и идентификатор PID

для каждой задачи */

 printk("%s[%d]\n", task->comm, task->pid);

}

Следует заметить, что организация цикла по всем задачам системы, в которой выполняется много процессов, может быть достаточно дорогостоящей операцией. Для применения такого кода должны быть веские причины (и отсутствовать другие альтернативы).

Создание нового процесса

В операционной системе Unix создание процессов происходит уникальным образом. В большинстве операционных систем для создания процессов используется метод порождения процессов (spawn). При этом создается новый процесс в новом адресном пространстве, в которое считывается исполняемый файл, и после этого начинается исполнение процесса. В ОС Unix используется другой подход, а именно разбиение указанных выше операций на две функции:

fork
и
exec
[15] .

15

Под

exec
будем понимать любую функцию из семейства
exec*
. В ядре реализован системный вызов
execve
, на основе которого реализованы библиотечные функции
execlp
,
execle
,
execv
и
execvp
.

В начале с помощью функции

fork
создается порожденный процесс, который является копией текущего задания. Порожденный процесс отличается от родительского только значением идентификатора
PID
(который является уникальным в системе), значением параметра
PPID
(идентификатор
PID
родительского процесса, который устанавливается в значение
PID
порождающего процесса), некоторыми ресурсами, такими как ожидающие на обработку сигналы (которые не наследуются), а также статистикой использования ресурсов. Вторая функция —
exec
— загружает исполняемый файл в адресное пространство процесса и начинает исполнять его. Комбинация функций
fork
и
exec
аналогична той одной функции создания процесса, которую предоставляет большинство операционных систем.

  • Читать дальше
  • 1
  • ...
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: