linux list详解
1 链表结构定义
首先
看链表的定义,位于:include\linux\types.h
truct list_head {
struct list_head *next, *prev;
};
一般将该数据结构嵌入到其他的数据结构中,从而使得内核可以通过链表的方式管理新的数据结构,比如struct device中:
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
...
struct list_head devres_head;//嵌入的链表
struct klist_node knode_class;
struct class *class;
const struct attribute_group **groups; /* optional groups */
void (*release)(struct device *dev);
struct iommu_group *iommu_group;
}
2 链表的定义和初始化
有两种方式来定义和初始化链表头:
(1)利用宏LIST_HEAD
(2)利用宏LIST_HEAD_INIT
例如定义链表mylist:
方法1:定义并初始化链表
LIST_HEAD(mylist);
方法2:先定义再初始化链表
struct list_head mylist; // 定义一个链表
INIT_LIST_HEAD(&mylist); // 用INIT_LIST_HEAD函数初始化链表。
看宏LIST_HEAD就知道就是用宏 INIT_LIST_HEAD
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
再看宏INIT_LIST_HEAD的定义:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
定义的mylist链表,宏展开就是
struct list_head mylist = { &(mylist), &(mylist) };
链表list_head结构只有两个成员:next和prev。next和prev都被赋值为链表mylist的地址,也就是说,链表初始化后next和prev都是指向自己的。
对于struct device 中嵌入的list成员devres_head的初始化如下这样:
struct device mydevice;
INIT_LIST_HEAD(&mydevice.list); //该函数简单地将list成员的prev和next指针指向自己。
所以链表结点在初始化时,就是将prev和next指向自己。对链表的初始化非常重要,因为如果使用一个