为什么在获取进程的子级时使用同级列表获取task_struct [英] why sibling list is used to get the task_struct while fetching the children of a process
问题描述
内核task_struct如下所示.我对两个成员(子级和同级成员)更感兴趣,因此我从此内核结构中删除了其他元素.
struct task_struct {//一些数据元素.struct list_head children;/*我的孩子的名单*/struct list_head同级;/*父母的子女名单中的链接*///一些数据成员};
子项"是进程子项的task_struct的双向循环链接列表.如果要从当前进程访问子项,则必须使用宏"list_for_each"遍历子项"列表,如下所示:>
struct task_struct * task;struct list_head *列表;list_for_each(list,& current-> children){task = list_entry(list,struct task_struct,同级);/*任务现在指向当前的一个孩子*/}
list_for_each最终将使用下一个子项初始化"list".现在,由于我们要遍历子项列表,因此理想情况下,我们应该从"list"指针中减去子项"列表的偏移量,以获取当前进程的tast_struct地址.strong>我们在此处传递兄弟"的原因是什么,最终导致具有不同偏移量的另一个列表?.
请注意:这是工作代码,我要了解的是为什么当应使用children指针计算正确的偏移量并因此计算孩子的task_struct地址时使用同级兄弟.
先谢谢了.
为了使用 struct list_head
将数据组织为链接列表,您必须声明 list root 并声明列表条目进行链接.根条目和子条目均具有相同的类型( struct list_head
). struct task_struct
条目的 children
条目是 root
. struct task_struct
的 sibling
条目是 list条目
.要查看差异,您必须阅读使用 children
和 sibling
的代码.对 children
使用 list_for_each
表示 children
是 root
.将 list_entry
用于 sibling
意味着 sibling
是 list条目
.
您可以在此处了解更多有关Linux内核列表的信息..>
问题:我们在此处传递兄弟"的原因是什么,它最终导致了具有不同偏移量的另一个列表?
答案:
如果列表是通过以下方式创建的:
list_add(& subtask->同级,& current->子级);
比
list_for_each(列表,& current->孩子)
将初始化指向 sibling
的列表指针,因此您必须使用 subling
作为list_entry的参数.这就是如何 linux内核列出设计的API.
但是,如果列表是通过另一种(错误)方式创建的:
list_add(& subtask->孩子,& current->同级);
您不必以这种方式(错误)遍历列表:
list_for_each(列表,& current->同级)
现在您必须使用 children
作为 list_entry
的参数.
希望,这会有所帮助.
Kernel task_struct looks like below.I am more interested in two members namely children and sibling , so i have removed other elements from this kernel structure .
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" is a doubly circular linked list of task_struct of the children of process .If I want to access the children from current process , I have to iterate over "children" list using macro "list_for_each" as below :
struct task_struct *task;
struct list_head *list;
list_for_each(list, ¤t->children) {
task = list_entry(list, struct task_struct, sibling); /* task now points to one of current’s children */
}
list_for_each will eventually initialize "list " with next children .Now since we are iterating through children list , we should ideally subtract the offset of "children" list from "list" pointer to get the tast_struct address for the current process .What is the reason we are passing "sibling" here which eventually a different list with different offset? .
Please note : It is working code , all I want to understand is why sibling is used when children pointer should be used to calculate correct offset and hence task_struct address for the children .
Thanks in Advance .
In order to organize data as linked list using struct list_head
you have to declare list root and declare list entry for linkage. Both root and child entries are the same type (struct list_head
). children
entry of struct task_struct
entry is a root
. sibling
entry of struct task_struct
is a list entry
. To see the differences, you have to read code, where children
and sibling
are used. Usage of list_for_each
for children
means what children
is a root
. Usage of list_entry
for sibling
means what sibling
is a list entry
.
You can read more about linux kernel lists here.
Question: What is the reason we are passing "sibling" here which eventually a different list with different offset?
Answer:
If the list was created this way:
list_add(&subtask->sibling, ¤t->children);
Than
list_for_each(list, ¤t->children)
Will initialize list pointers to sibling
, so you have to use subling
as parameter to list_entry. That's how linux kernel lists API designed.
But, If the list was created in another (wrong) way:
list_add(&subtask->children, ¤t->sibling);
Than you have to iterate the list this (wrong) way:
list_for_each(list, ¤t->sibling)
And now you have to use children
as parameter for list_entry
.
Hope, this helps.
这篇关于为什么在获取进程的子级时使用同级列表获取task_struct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!