Linux のプロセスの内部構成 (家族関係に関して)

Linux のプロセスの内部構成 (家族関係に関して)

私の理解では、プロセス記述子は二重リンク リスト データ構造に格納されます。ただし、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;「整理」された二重リンク リストですが、間違っている可能性もあります。

関連情報