我是靠谱客的博主 虚心黄豆,最近开发中收集的这篇文章主要介绍list_for_each & list_entry & 对内核链表的理解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、list_for_each

1.list_for_each原型
#define list_for_each(pos, head)
    for (pos = (head)->next, prefetch(pos->next); pos != (head);
    pos = pos->next, prefetch(pos->next))
它实际上是一个 for 循环,利用传入的pos 作为循环变量,从表头 head开始,逐项向后(next方向)移动 pos ,直至又回到 head (prefetch() 可以不考虑,用于预取以提高遍历速度)。
注意:此宏必要把list_head放在数据结构第一项成员,至此,它的地址也就是结构变量的地址。

2.使用方法(以访问当前进程的子进程为例):

struct list_head {
 struct list_head *next, *prev;
};

在struct task_struct 中有如下定义:
struct list_head children;

所以

struct task_struct *task;

struct list_head *list;

list_for_each(list,&current->chilidren) {

              task = list_entry(list, struct task_struct, sibling);/*task指向当前的某个子进程*/

}

其中list_entry宏定义如下,其作用是根据ptr(指向结构成员变量的指针)得到指向其容器(也就是结构体)的地址


#define list_entry(ptr, type, member) /
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

    ptr是指向list_head类型链表的指针,type为一个结构,而member为结构type中的一个域,类型为list_head,这个宏返回指向type结构的指针。在内核代码中大量引用了这个宏,因此,搞清楚这个宏的含义和用法非常重要。

   
设有如下结构体定义:
typedef struct xxx
{
     ……(结构体中其他域,令其总大小为size1)
     type1 member;
     ……(结构体中其他域)
}type;


定义变量:
   type a;
   type * b;
   type1 * ptr;
执行:
   ptr=&(a.member);
   b=list_entry(ptr,type,member);
则可使b指向a,得到了a的地址

如何做到的呢?

先看&((type *)0)->member:
把“0”强制转化为指针类型,则该指针一定指向“0”(数据段基址)。因为指针是“type *”型的,所以可取到以“0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏移字节数。

 


再来看 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
(char *)(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type *)0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者一减便得出该结构体的地址。转换为 (type *)型的指针,大功告成。

==============

 list_entry定义如下:

/**
* list_entry - get the struct for this entry
* @ptr:        the &struct list_head pointer.
* @type:        the type of the struct this is embedded in.
* @member:        the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) /
        ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))


对内核链表理解
http://blog.csdn.net/wenqian1991/article/details/44515713

最后

以上就是虚心黄豆为你收集整理的list_for_each & list_entry & 对内核链表的理解的全部内容,希望文章能够帮你解决list_for_each & list_entry & 对内核链表的理解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部