.png)
私の理解では、プロセス記述子は二重リンク リスト データ構造に格納されます。ただし、fork
同じプロセスに対して複数の子を作成するために使用できるため、複数のプロセスが 1 つの親プロセスを指すため、ツリー構造があると考えられます。どちらが正しいですか? プロセス記述子はプロセスと異なりますか?
答え1
fork()
プロセス記述子をコピーして新しいプロセスを作成します。したがって、2つのプロセスは(少なくとも最初は)いくつかのデータを共有しますが、1つのプロセスが起動するとすぐに変化コピーオンライト機構により、変更が実際に変更を行ったプロセスにのみ限定されます。これは、UNIX でのプロセス生成の標準機構です。
もちろん、これによりプロセス間にかなり自然な親子関係が作成されますが、これはカーネルの内部表現とは無関係です。プロセス記述子は、リンク リスト、ツリー、ハッシュ テーブル、またはその他の (多かれ少なかれ) 適切な構造として実装できます。実際に必要なのは、親プロセス (および場合によっては子プロセスも) を指すカーネル プロセス記述子の場所だけです。これを構造の主要部分として使用するかどうかは、設計上の決定です。このようなことを決定するときに関係する多くの要素の 1 つは、たとえば、親プロセスが終了した後に何が起こるかです。UNIX では、プロセスはinit
孤立したプロセス (およびすべての子プロセス) を採用します。
答え2
あなたの混乱は、(1) プロセス記述子を整理しておくことと、(2) 親子関係という 2 つの事柄が混同されていることに起因しています。
次にどのプロセスを実行するか、または (一般的に) どのプロセスにシグナルを送信するかを決定するために、親/子関係は必要ありません。したがって、Linux ( 3.11.5 カーネル ソースでtask_struct
見つけたもの) には次のものがあります。linux/sched.h
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 */
おっしゃる通り、子/親関係のツリー構造は存在しますが、別のリストと親へのポインターに隠されているようです。
有名な二重リンク リストは、3.11.5struct task_struct
構造定義では明らかではありません。コードを正しく読めば、コメントされていない構造体要素はstruct list_head tasks;
「整理」された二重リンク リストですが、間違っている可能性もあります。