fork()
erstellt einen neuen Prozess durch Kopieren des Prozessdeskriptors. Daher teilen sich die beiden Prozesse (zumindest anfangs) einige Daten, aber sobald ein Prozess beginnt, sich zu ändern Der Copy-on-Write-Mechanismus stellt sicher, dass die Änderung nur für den Prozess lokalisiert wird, der sie tatsächlich vorgenommen hat. Es ist der Standardmechanismus für das Spawnen von Prozessen unter UNIX.
Dadurch entsteht natürlich eine recht natürliche Eltern-Kind-Beziehung zwischen Prozessen, die jedoch unabhängig von der internen Repräsentation im Kernel ist. Prozessdeskriptoren können als verknüpfte Liste, Baum, Hash-Tabelle oder jede andere (mehr oder weniger) geeignete Struktur implementiert werden. Alles, was man wirklich braucht, ist ein Platz im Kernel-Prozessdeskriptor, der auf den übergeordneten Prozess (und möglicherweise auch auf untergeordnete Prozesse) zeigt. Ob es als wichtiger Teil der Struktur verwendet wird oder nicht, ist eine Designentscheidung. Eines der vielen Dinge, die ins Spiel kommen, wenn man so etwas entscheidet, ist zum Beispiel, was passiert, wenn der übergeordnete Prozess beendet wird - unter UNIX die init
Der Prozess übernimmt verwaiste Prozesse (mit allen ihren untergeordneten Prozessen).
Ihre Verwirrung rührt daher, dass Sie zwei Dinge vermischen:(1) die Organisation der Prozessdeskriptoren und (2) die Eltern-/Kind-Beziehung.
Sie brauchen die Eltern/Kind-Beziehung nicht, um zu entscheiden, welcher Prozess als nächstes ausgeführt werden soll oder (allgemein) an welchen Prozess ein Signal gesendet werden soll. Also das Linux task_struct
(was ich in linux/sched.h
gefunden habe für die Kernelquelle 3.11.5) hat:
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 */
Sie haben Recht, eine Baumstruktur existiert für die Kind/Eltern-Beziehung, aber sie scheint in einer anderen Liste und einem Zeiger auf das Elternteil verborgen zu sein.
Die berühmte doppelt verknüpfte Liste ist in 3.11.5 struct task_struct
nicht offensichtlich Strukturdefinition. Wenn ich den Code richtig gelesen habe, ist das unkommentierte Strukturelement struct list_head tasks;
ist die "organisierende" doppelt verknüpfte Liste, aber ich könnte mich irren.