内核链表
-------Dream
头文件:include/linux/list.h
内核链表数据结构:
struct list_head
{
struct list_head *next,*prev;
}; //内核的链表具备双链表功能,是双向循环链表
链表操作:
1.初始化链表头
INIT_LIST_HEAD(struct list_head *list);
/*
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
*/
2.插入节点
list_add(struct list_head *new,struct list_head_head *head);
list_add_tail(struct list_head *new,struct list_head *head);
/*
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void __list_add(struct list_head *new,
struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
*/
3.删除节点
list_del(struct list_head *entry);
/*
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (void *)0xDEADBEEF;
entry->prev = (void *)0xBEEFDEAD;
}
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
*/
4.提取数据结构
list_entry(ptr,type,member); //ptr已知数据结构节点的指针,member所对应结构的成员名
/*
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
*/
5.链表的遍历
list_for_each(struct list_head *pos,struct list_head *head);
/*
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
例如:
struct list_head *entry;
struct list_head cs46xx_devs; //链表头
list_for_each(entry,&cs46xx_devs){
card=list_entry(entry,struct cs_cadr,list);
if(card->dev==minor)
break;
}
*/
内核链表操作实例:
#include <linux/list.h>
MODULE_LICENST("GPL");
struct student
{
char name[100];
int num;
struct list_head list;
};
struct student *pstudent;
struct student *tmp_student;
struct list_head student_list;
struct list_head *pos;
int mylist_init()
{
int i=0;
INIT_LIST_HEAD(&student_list); //初始化内核链表头
pstudent=kmalloc(sizeof(struct student)*5,GFP_KERNEL); //为这个结构体分配存储空间
memset(pstudent,0,sizeof(sturct student)*5); //清空
for(int i=0;i<5;i++)
{
sprintf(pstuent[i].name,"student%d",i+1);
pstudent[i].num=i+1;
list_add(&(pstudent[i].list),&student_list); //在student_list中插入节点
}
list_for_each(pos,&student_list) //遍历链表
{
tmp_student=list_entry(pos,struct student,list);
printk("student %d name:%s\n",tmp_student->num,tmp_student->name);
}
return 0;
}
void mylist_exit()
{
int i;
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list)); //删除内核链表
}
kfree(pstudent); //释放节点
}
module_init(mylist_init);
module_exit(mylist_exit);