个人首先参考了如下两篇文章:

http://blog.csdn.net/hongchangfirst/article/details/7076225

http://hi.baidu.com/mynana/blog/item/1da1ba99239ceb006f068c48.html

一个侧重于应用,另一个则介绍了部分的内部原理。

这里记录我个人的理解。

参考文献:《linux内核设计与实现》,陈莉君

文中第25页,有如下一段话:

可以按照如下方式依次访问子进程:

structtask_struct *task;

structlist_head *list;

//关于list_head结构请参考:

//http://hi.baidu.com/wjq_qust/blog/item/bfd9a2ec94903e2762d09fee.html

list_for_each(list,&current->children){

task=list_entry(list,structtask_struct,sibling);

}

list_for_each定义如下:

#definelist_for_each(pos,head) \

for(pos=(head)->next;prefetch(pos->next),pos!=head;pos=pos->next)

list_entry定义如下:

#definelist_entry(ptr,type,member) container_of(ptr,type,member)

作用和用法在这里不做讲解,可参考上述的两篇文章。

在task_struct结构体中有如下的一个成员:

structlist_head sibling;

源码注释其为://linkage in my parent’schildren list

即该指针存放本进程的父进程的子进程的list.

那么上述例子(依次访问子进程)中关于list_entry的实现就很好理解了。

container_of定义中,首先将通过list_for_each获得的list_head类型的指针赋予一个临时定义的变量__mptr,存放了该子进程在父进程的子进程list中的位置,其实也就是该子进程的task_struct结构体中的sibling指针,而后通过offsetof获得偏移量之后,通过减法关系,即获得了该子进程的task_struct的指针。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐