fork()
crée un nouveau processus en copiant le descripteur de processus. Par conséquent, les deux processus partagent (au moins initialement) certaines données, mais dès qu'un processus commence à changer le mécanisme de copie sur écriture garantit que la modification est localisée uniquement sur le processus qui l'a réellement effectuée. Il s'agit du mécanisme standard de création de processus sous UNIX.
Cela crée bien sûr une relation parent-enfant plutôt naturelle entre les processus, mais cela est indépendant de la représentation interne dans le noyau. Les descripteurs de processus peuvent être implémentés sous la forme d'une liste chaînée, d'un arbre, d'une table de hachage ou de toute autre structure (plus ou moins) appropriée. Tout ce dont on a vraiment besoin est de placer dans le descripteur de processus du noyau qui pointe vers le processus parent (et éventuellement les processus enfants également). Qu'il soit ou non utilisé comme élément clé de la structure est une décision de conception. L'une des nombreuses choses qui entrent en jeu lors de la décision d'une telle chose est par exemple ce qui se passe une fois que le processus parent se termine - sous UNIX, le init
processus adopte des processus orphelins (avec tous leurs processus enfants).
Votre confusion provient du mélange de deux choses :(1) garder les descripteurs de processus organisés et (2) la relation parent/enfant.
Vous n'avez pas besoin de la relation parent/enfant pour décider quel processus exécuter ensuite ou (en général) à quel processus envoyer un signal. Ainsi, Linux task_struct
(que j'ai trouvé dans linux/sched.h
pour la source du noyau 3.11.5) a :
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 */
Vous avez raison, une arborescence existe pour la relation enfant/parent, mais elle semble être cachée dans une autre liste, et un pointeur vers le parent.
La célèbre liste doublement liée n'est pas évidente dans le struct task_struct
3.11.5 définition de structure. Si j'ai bien lu le code, l'élément struct non commenté struct list_head tasks;
est la liste doublement liée "d'organisation", mais je peux me tromper.