为什么在获取进程的子级时使用同级列表获取task_struct

SAC*_*YAL 5 c linux linux-kernel

内核task_struct如下所示。我对两个成员(子级和同级成员)更感兴趣,因此我从此内核结构中删除了其他元素。

  struct task_struct{
        // some data elements .


          struct list_head children;      
              /* list of my children */

          struct list_head sibling;
              /* linkage in my parent's children list */
        //some data members 
        };
Run Code Online (Sandbox Code Playgroud)

“子项”是进程子项的task_struct的双向循环链接列表。如果要从当前进程访问子项,则必须使用宏“ list_for_each”遍历“子项”列表,如下所示:

struct task_struct *task; 
struct list_head *list;
list_for_each(list, &current->children) { 
task = list_entry(list, struct task_struct, sibling); /* task now points to one of current’s children */ 
}
Run Code Online (Sandbox Code Playgroud)

list_for_each最终将使用下一个子项初始化“ list”。现在,由于我们要遍历子项列表,因此理想情况下,我们应该从“ list”指针中减去“子项”列表的偏移量,以获取当前进程的tast_struct地址。是什么原因导致我们在此处传递“兄弟”,而最终导致具有不同偏移量的另一个列表?

请注意:这是有效的代码,我要了解的是为什么当应使用children指针计算正确的偏移量并因此计算child的task_struct地址时为什么使用同级。

提前致谢 。

ale*_*der 4

为了使用链接列表来组织数据,struct list_head您必须声明列表根并声明链接的列表条目。根条目和子条目的类型相同 ( struct list_head)。children条目的条目struct task_struct是一个rootsibling的条目struct task_struct是 a list entry。要查看差异,您必须阅读代码,了解使用children和的位置sibling。使用list_for_eachforchildren意味着什么children是 a root。使用list_entryforsibling意味着什么sibling是 a list entry

您可以在此处阅读有关 Linux 内核列表的更多信息。

问题:我们在这里传递“兄弟”(最终是具有不同偏移量的不同列表)的原因是什么?

回答:

如果列表是这样创建的:

list_add(&subtask->sibling, &current->children);
Run Code Online (Sandbox Code Playgroud)

然后

list_for_each(list, &current->children)
Run Code Online (Sandbox Code Playgroud)

将初始化列表指针sibling,因此您必须将其用作siblinglist_entry 的参数。这就是linux内核列出API设计的方式。

但是,如果列表是以另一种(错误)方式创建的:

list_add(&subtask->children, &current->sibling);
Run Code Online (Sandbox Code Playgroud)

然后你必须以这种(错误的)方式迭代列表:

list_for_each(list, &current->sibling)
Run Code Online (Sandbox Code Playgroud)

现在你必须使用children作为参数list_entry

希望这可以帮助。

  • @Olaf:`*children* 分配了列表 *root* 角色` = `*children* 是一个 *root*`。这是“角色”一词的普遍含义。`*sibling* 分配了列表 *linkage* 角色` = `*sibling* 用于 *linkage* 目的`,即用于给定列表条目与其他条目的 **链接**。这是真的。 (2认同)
  • @SACHINGOYAL:“current->children”是根,但您迭代“.siblings”字段。您已经知道父任务(“当前”)的地址,但不知道子任务的地址。这就是为什么你在 `container_of()` 宏中使用 `.siblings` 字段。请注意,某些*子*任务的“.children”字段是*该子任务的子任务列表*。这是完全不同的任务,其中“current”是祖父母。 (2认同)