1. 在Linux内核中使用了大量的链表结构来组织数据,链表结构的定义为:
struct list_head { struct list_head* next; struct list_head* prev; };
list_head结构包含两个只想list_head结构的指针prev和next,由此可见,内核的链表具备双链表的功能。实际上,通常他都组织成双向循环链表。
2. Linux内核中提供的链表操作主要有:
①INIT_LIST_HEAD(struct list_head* head): 初始化链表头
static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; }
②list_add(struct list_head* new, struct list_head* head): 链表头插入(在head后插入)
③list_add_tail(struct list_head* new, struct list_head* head): 链表尾插入(在head前插入)
④list_del(struct list_head* head): 删除节点
⑤list_entry(ptr, type, member): 提取数据结构(根据成员变量member的地址ptr,返回指向结构体type的指针)
⑥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)
3.简单实例:
#include <linux/init.h> #include <linux/module.h> typedef struct _ListTest { struct list_head head; int value; } ListTest; MODULE_LICENSE("GPL"); MODULE_AUTHOR("Kevin"); MODULE_VERSION("V1.0"); MODULE_DESCRIPTION("Print Hello world"); struct list_head header; static int ListInit(void) { int i = 0; ListTest listTest[5]; struct list_head* pNode = NULL; ListTest* pTestNode = NULL; printk(KERN_INFO"List init! "); INIT_LIST_HEAD(&header); for(i = 0; i < 5; i++) { listTest[i].value = i; } list_add_tail(&(listTest[0].head), &header); list_add_tail(&(listTest[1].head), &header); list_add_tail(&(listTest[2].head), &header); list_add_tail(&(listTest[3].head), &header); list_add_tail(&(listTest[4].head), &header); list_for_each(pNode, &header) { if(pNode != NULL) { pTestNode = list_entry(pNode, ListTest, head); printk(KERN_INFO"pTestNode->value = %d ", pTestNode->value); } } list_del(&header); return 0; } static void ListExit(void) { printk(KERN_INFO"List exit! "); } module_init(ListInit); module_exit(ListExit);