Читать «Разработка ядра Linux» онлайн - страница 39
Роберт Лав
struct task_struct *p, *reaper = father;
struct list_head *list;
if (father->exit_signal != -1)
reaper = prev_thread(reaper);
else
reaper = child_reaper;
if (reaper == father)
reaper = child_reaper;
Этот программный код присваивает переменной reaper указатель на другое задание в группе потоков данного процесса. Если в этой группе потоков нет другого задания, то переменной reaper
присваивается значение переменной child_reaper,
которая содержит указатель на процесс init
. Теперь, когда найден подходящий родительский процесс, нужно найти все порожденные процессы и установить для них полученное значение родительского процесса, как показано ниже.
list_for_each(list, &father->children) {
p = list_entry(list, struct task_struct, sibling);
reparent_thread(p, reaper, child_reaper);
}
list_for_each(list, &father->ptrace_children) {
p = list_entry(list, struct task_struct, ptrace_list);
reparent_thread(p, reaper, child_reaper);
}
В этом программном коде организован цикл по двум спискам: по списку порожденных процессов
Когда для процессов переназначение родительского процесса прошло успешно, больше нет риска, что какой-либо процесс навсегда останется в состоянии зомби. Процесс init
периодически вызывает функцию wait()
для всех своих порожденных процессов и, соответственно, удаляет все зомби-процессы, назначенные ему.
Резюме
В этой главе рассмотрена важная абстракция операционной системы — процесс. Здесь описаны общие свойства процессов, их назначение, а также представлено сравнение процессов и потоков. Кроме того, описывается, как операционная система Linux хранит и представляет информацию, которая относится к процессам (структуры task_struct
и thread_info
), как создаются процессы (вызовы clone()
и fork()
), каким образом новые исполняемые образы загружаются в адресное пространство (семейство вызовов exec()
), иерархия процессов, каким образом родительский процесс собирает информацию о своих потомках (семейство функций wait()
) и как в конце концов процесс завершается (непроизвольно или с помощью вызова exit()
).