为什么兄弟列表用于在获取进程的子进程时获取task_struct

时间:2016-01-10 11:18:21

标签: c linux linux-kernel

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

library(ggplot2)
sampleDataFrame <- read.table(file.choose(), sep=",", header=T)
sampleDataFrame$userId <- factor(sampleDataFrame$userId)
p1 <- ggplot(sampleDataFrame, aes(x=percentage, y=temp, colour=userId)) + geom_line()
print(p1)

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

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

list_for_each最终将使用下一个子项初始化“list”。现在我们正在迭代子列表,我们理想情况下应从“list”指针中减去“children”列表的偏移量,以获取当前进程的tast_struct地址。 strong>我们在这里传递“兄弟姐妹”的原因是什么,最终是一个不同的偏差列表?。

请注意:这是工作代码,所有我想了解的是为什么当使用子指针来计算正确的偏移量并因此为子节点设置task_struct地址时使用兄弟。

先谢谢。

4 个答案:

答案 0 :(得分:3)

要使用struct list_head将数据整理为链接列表,您必须声明列出根并声明列表条目以进行链接。根和子条目的类型相同(struct list_head)。 children条目的struct task_struct条目为rootsibling的{​​{1}}条目为struct task_struct。要查看差异,您必须阅读使用list entrychildren的代码。对sibling使用list_for_each表示childrenchildren。对root使用list_entry表示siblingsibling

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

问题:我们通过什么原因&#34;兄弟姐妹&#34;这里哪个最终有不同的偏移列表?

<强>答案:

如果列表是以这种方式创建的:

list entry

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

将列表指针初始化为list_for_each(list, &current->children) ,因此您必须使用sibling作为list_entry的参数。那个如何 linux内核列出了API设计。

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

subling

比你必须迭代这个列表(错误的):

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

现在您必须使用list_for_each(list, &current->sibling) 作为children的参数。

希望,这有帮助。

答案 1 :(得分:1)

以下是可能对将来有所帮助的图形表示。顶部的框代表父母,底部的两个框代表孩子

enter image description here

答案 2 :(得分:1)

这里是除先前答案以外的图片。 相同的过程既可以是父母也可以是孩子(如图中的Parent1),我们需要区分这两个角色。

直观地,如果Parent0的children指向Parent1的children,则Parent0.children.next->next(图片上的绿色圆圈)与Parent1.children.next相同指向Parent1的一个孩子,而不是Parent0的下一个孩子。

enter image description here

答案 3 :(得分:0)

但是为什么不呢?

列表是通过以下方式创建的:

list_add(subtask, &current->children);

以这种方式重复:

list_for_each(list, &current->children) {
  child = (struct task_struct *)list
}