1、介绍
linux内核链表重要是针对:普通链表无法管理所有结构体节点串联起来;普通链表利用一种结构只能表示一个对象。加入我只想对某个节点添加某种属性int number;将会需要改变所有节点结构体。
struct list_node{
int value1;
char value2;
struct list_node *next;
struct list_node *prev;
};
改成内核链表的方式:
struct list_node{
struct list_node *next;
struct list_node *prev;
};
struct score{
int value1;
char value2;
struct list_node *head_list;
}
2、主要的几个函数(函数实现可以直接查看后面代码)
1、内核链表的几个重要函数
(1)INIT_LIST_HEAD()创建链表
(2)list_add()在链表头插入
(3)list_add_tail
(4)list_del()
(5)list_entry()
(6)list_for_each()
用图解释一下链表头插入
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;
}
void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
3、应用层代码
#includestruct list_head{ struct list_head *prev; struct list_head *next; }; struct score{ int num; int englist; int math; struct list_head list; }; #define prefetch(x) __builtin_prefetch(x) #define list_for_each(pos, head) for ( pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define list_entry(ptr, type, member) container_of(ptr, type, member) #define container_of(ptr, type, member) ( { const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) ); } ) 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; } void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = (void *) 0; entry->prev = (void *) 0; } void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } struct list_head score_head; struct score stu1, stu2,stu3; struct list_head *pos; struct score *tmp; int main(void) { INIT_LIST_HEAD(&score_head); stu1.englist=99;stu1.math=98;stu1.num=1001; stu2.englist=9;stu2.math=8;stu2.num=1002; stu3.englist=69;stu3.math=68;stu3.num=1003; list_add_tail(&(stu1.list),&score_head); list_add_tail(&(stu2.list),&score_head); list_add_tail(&(stu3.list),&score_head); list_for_each(pos,&score_head){ tmp=list_entry(pos,struct score,list);//这个地方list为何可以直接使用? printf("math=%dn",tmp->math); } return 0; }
sl相关描述:(119条消息) linux内核链表的实现和使用和详解_ZJE-CSDN博客_内核链表使用



