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()
).
Процесс — это фундаментальная и ключевая абстракция, которая является основой всех современных операционных систем и, в конце концов, причиной, по которой вообще существуют операционные системы (чтобы выполнять программы).
В следующей главе рассказывается о планировании выполнения процессов — изящной и интересной функции ядра, благодаря которой ядро принимает решение, какие процессы должны выполняться, в какое время и в каком порядке.
Глава 4
Планирование выполнения процессов
В предыдущей главе были рассмотрены процессы — абстракция операционной системы, связанная с активным программным кодом. В этой главе представлен планировщик процессов — код, который позволяет процессам выполняться.
Планировщик (