linux驅動開發--內核鏈表
1、內核鏈表定義
在<linux/list.h>中定義
struct list_head{ struct list_head *next, *prev; };在list_head結構中包含兩個指向list_head結構的指針next和prev,在實際使用中,它通常被組織成雙向循環鏈表。
內核鏈表結構體不包含數據域,隻包含維護鏈表的指針域。
內核鏈表被包含在其他數據結構體中使用。
初始化鏈表頭INIT_LIST_HEAD函數
void INIT_LIST_HEAD(struct list_head *list);
list:待初始化鏈表頭
插入節點list_add函數
void list_add(struct list_head *new, struct list_head *head);
void list_add_tail(struct list_head *new, struct list_head *head);
new:待插入到鏈表的新節點
head:待插入到鏈表的鏈表頭
刪除節點list_del函數
void list_del(struct list_head *entry);
entry:待刪除的節點
提取數據結構list_entry宏
#define list_entry(ptr, type, member) container_of(ptr, type, member)
ptr:當前鏈表節點指針
type:包含該鏈表的數據結構體類型
member:在數據結構體類型中的list_head成員名稱
返回:獲取的數據結構體指針
實際是通過已知數據結構體中鏈表節點指針ptr,獲取包含該鏈表節點的數據結構體指針
遍曆鏈表list_for_each宏
#define list_for_each(pos, head) for(pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next)
#define list_for_each_safe(pos, n, head) for(pos = (head)->next, n= pos->next; pos !=(head); pos = n, n = pos->next)
pos:list_head指針類型的循環變量
n:list_head指針類型的循環變量
head:待遍曆鏈表的鏈表頭
2、實例代碼:
/** *Copyright (c) 2013.TianYuan *All rights reserved. * *文件名稱: listtest.c *文件標識: 內核鏈表的使用 * *當前版本:1.0 *作者:wuyq * *取代版本:xxx *原作者:xxx *完成日期:2013-11-18 */ #include <linux/init.h> #include <linux/module.h> #include <linux/err.h> #include <linux/slab.h> #include <linux/list.h> MODULE_LICENSE("GPL"); #define EMPLOYEE_NUM 10 struct employee { char name[20]; int id; int salary; int age; struct list_head list; }; /*定義鏈表頭節點*/ struct list_head employee_list; struct employee *employeep = NULL;/*保存首地址*/ struct list_head *pos = NULL;/*list_for_each*/ struct employee *employee_tmp = NULL; static int __init listtest_init(void) { int i = 0; /*初始化鏈表頭節點*/ INIT_LIST_HEAD(&employee_list); /*申請employee空間*/ employeep = kmalloc(sizeof(struct employee)*EMPLOYEE_NUM, GFP_KERNEL); if(IS_ERR(employeep)){ printk("kmalloc failed!\n"); return -ENOMEM; } memset(employeep, 0, sizeof(struct employee)*EMPLOYEE_NUM); /*初始化每個struct*/ for(i=0; i<EMPLOYEE_NUM; i++){ sprintf(employeep[i].name, "employee%d", i); /*true*/sprintf((employeep+i)->name, "employee%d", i); employeep[i].id = 10000 + i; employeep[i].salary = 10000 + 1000*i; /*添加節點到鏈表中*/ list_add(&(employeep[i].list), &employee_list); } /*鏈表節點的遍曆*/ list_for_each(pos, &employee_list){ employee_tmp = list_entry(pos, struct employee, list); printk("employee name :T=%s\tID:%d\tSalary:%d!\n", employee_tmp->name, employee_tmp->id, employee_tmp->salary); } return 0; } static void __exit listtest_exit(void) { int i = 0; for(i=0; i<EMPLOYEE_NUM; i++){ list_del(&(employeep[i].list)); } kfree(employeep); } module_init(listtest_init); module_exit(listtest_exit);
KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A PWD := $(shell pwd) obj-m += listtest.o default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: @rm -f *.o *.ord* *.sy* *.mod.* *.ko
最後更新:2017-04-03 12:53:59
上一篇:
linux驅動開發--字符設備:自動創建設備節點
下一篇:
Java to download a file from internet
VPC最佳實踐(二):VPC內如何使用雲產品
跟著實例學習ZooKeeper的用法: 隊列
站在5G大門口,重新認識高通的三組基因
前端在人工智能時代能做些什麼?
????????????????????????? ???????????????????????????????????????-??????-????????????-?????????
Sql Server 常用函數
雲計算市場群雄並起,“架構雲”突破重圍成為新寵
Android串口通信(基於Tiny6410平台)
遊戲安全資訊精選 2017 年第一期:流量攻擊態勢嚴峻,微軟7月漏洞匯總和修複建議
深入理解Java內存模型(四)——volatile