gpt4 book ai didi

c - 为什么在获取进程的子进程时使用兄弟列表来获取 task_struct

转载 作者:IT王子 更新时间:2023-10-29 01:13:37 25 4
gpt4 key购买 nike

内核 task_struct 如下所示。我对两个成员更感兴趣,即 children 和 sibling ,所以我从这个内核结构中删除了其他元素。

  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
};

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

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 */
}

list_for_each 最终会用下一个子项初始化“list”。既然我们正在遍历子项列表,理想情况下我们应该从“list”指针中减去“children”列表的偏移量以获得当前进程的 tast_struct 地址。< strong>我们在这里传递“兄弟”的原因是什么,它最终是一个具有不同偏移量的不同列表?。

请注意:它是工作代码,我想了解的是为什么在应该使用子指针来计算正确的偏移量并因此计算子项的 task_struct 地址时使用 sibling 。

提前致谢。

最佳答案

为了使用struct list_head 将数据组织为链表,您必须声明list root 并声明list entry 以进行链接。根条目和子条目都是同一类型 (struct list_head)。 struct task_struct 条目的 children 条目是一个 rootstruct task_structsibling 条目是一个列表条目。要查看差异,您必须阅读代码,其中使用了 childrensiblinglist_for_each 用于 children 意味着 children 是一个 rootlist_entry 用于 sibling 意味着 sibling 是一个 list entry

您可以阅读更多关于 linux 内核列表的信息 here .

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

答案:

如果列表是这样创建的:

list_add(&subtask->sibling, &current->children);

然后

list_for_each(list, &current->children)

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

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

list_add(&subtask->children, &current->sibling);

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

list_for_each(list, &current->sibling)

现在您必须使用 children 作为 list_entry 的参数。

希望这对您有所帮助。

关于c - 为什么在获取进程的子进程时使用兄弟列表来获取 task_struct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34704761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com