为什么在获取进程的子级时使用同级列表获取task_struct [英] why sibling list is used to get the task_struct while fetching the children of a process

查看:42
本文介绍了为什么在获取进程的子级时使用同级列表获取task_struct的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

内核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, &current->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, &current->children);

Than

list_for_each(list, &current->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, &current->sibling);

Than you have to iterate the list this (wrong) way:

list_for_each(list, &current->sibling)

And now you have to use children as parameter for list_entry.

Hope, this helps.

这篇关于为什么在获取进程的子级时使用同级列表获取task_struct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆