%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D0%B2%20%D0%B2%20Linux.png)
Насколько я понимаю, дескрипторы процессов хранятся в структуре данных двусвязного списка. Но их fork
можно использовать для создания нескольких потомков для одного и того же процесса, поэтому я думаю, что это древовидная структура, поскольку несколько процессов будут указывать на один родительский процесс. Что правильно? Отличаются ли дескрипторы процессов от процессов?
решение1
fork()
создает новый процесс путем копирования дескриптора процесса. Следовательно, два процесса разделяют (по крайней мере, изначально) некоторые данные, но как только один процесс запускаетсяменяетсяэто, механизм копирования-при-записи, обеспечивает локализацию изменения только в процессе, который его фактически сделал. Это стандартный механизм для порождения процессов в UNIX.
Конечно, это создает довольно естественную связь родитель-потомок между процессами, но это не зависит от внутреннего представления в ядре. Дескрипторы процессов могут быть реализованы как связанный список, дерево, хэш-таблица или любая другая (более или менее) подходящая структура. Все, что действительно нужно, это поместить в дескриптор процесса ядра, который указывает на родительский процесс (и, возможно, также на дочерние процессы). Будет ли он использоваться или нет в качестве ключевой части структуры — это решение проекта. Одна из многих вещей, которые вступают в игру при принятии такого решения, — это, например, то, что происходит после завершения родительского процесса — в UNIX процесс init
принимает осиротевшие процессы (со всеми их дочерними процессами).
решение2
Ваша путаница возникает из-за смешения двух вещей: (1) упорядочивания описаний процессов и (2) родительско-дочерних отношений.
Вам не нужны родительские/дочерние отношения, чтобы решить, какой процесс запустить следующим, или (в общем случае) какому процессу доставить сигнал. Итак, Linux task_struct
(который я нашел в linux/sched.h
исходниках ядра 3.11.5) имеет:
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
Вы правы, древовидная структура для отношений «ребенок/родитель» существует, но она, похоже, скрыта в другом списке и указателе на родителя.
Знаменитый двусвязный список неочевиден в struct task_struct
определении структуры 3.11.5. Если я правильно прочитал код, то не прокомментированный элемент структуры struct list_head tasks;
— это «организующий» двусвязный список, но я могу ошибаться.