Linux 中进程的内部组织(关于家族关系)

COD*_*ror 6 linux process kernel

据我了解,进程描述符存储在双向链表数据结构中。但是fork可以用来为同一个进程创建多个子进程,所以让我觉得有一个树结构,因为多个进程会指向一个父进程。哪个是正确的?进程描述符与进程不同吗?

pet*_*rph 6

fork()通过复制进程描述符创建一个新进程。因此,这两个进程确实共享(至少在最初)一些数据,但是一旦一个进程开始更改它,写时复制机制确保更改仅本地化到实际创建它的进程。它是 UNIX 上进程生成的标准机制。

这当然会在进程之间创建一种相当自然的父子关系,但这与内核中的内部表示无关。进程描述符可以实现为链表、树、哈希表或任何其他(或多或少)合适的结构。真正需要的只是放在指向父进程(也可能是子进程)的内核进程描述符中。是否将其用作结构的关键部分是设计决策。在决定这样的事情时,许多事情都会起作用,例如,一旦父进程退出会发生什么 - 在 UNIX 上,init进程采用孤立进程(及其所有子进程)。


Bru*_*ger 5

您的困惑源于混合了两件事:(1)保持流程描述符的组织,以及(2)父/子关系。

您不需要父/子关系来决定接下来运行哪个进程,或者(通常)向哪个进程传递信号。因此,Linux task_struct(我在linux/sched.h3.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 */
Run Code Online (Sandbox Code Playgroud)

你是对的,存在一个用于子/父关系的树结构,但它似乎隐藏在另一个列表中,以及一个指向父的指针。

著名的双向链表在 3.11.5struct task_struct结构定义中并不明显。如果我正确阅读了代码,未注释的结构元素struct list_head tasks;是“组织”双向链表,但我可能是错的。