linux内核链表使用例,Linux设备驱动工程师之路——内核链表的使用
一、重要知識點
1.內核鏈表和普通鏈表的區別
內核鏈表是一個雙向鏈表,但是與普通的雙向鏈表又有所區別。內核鏈表中的鏈表元素不與特定類型相關,具有通用性。
我們先來看一幅圖
kernel list展示的是內核鏈表的結構,normallist展示的是普通鏈表的結構。head是鏈表頭,p1,p2,p3是鏈表節點。從圖中可以看出普通鏈表的p1的next指針是指向的結構體p2的地址,p2的pre指針指向p1結構體的地址。而內核鏈表的p1的next指向的是p2結構體中包含pre和next部分的地址,的p2的pre指向的是p1結構體中包含pre和next部分的地址。依此類推,這就是區別。內核結構元素不與特定類型結構相關,任何結構體都可通過內核的添加成為鏈表中的節點。
2.內核鏈表的具體操作
鏈表數據結構的定義
structlist_head
{
struct list_head *next, *prev;
}
初始化鏈表頭
INIT_LIST_HEAD(list_head*head)
插入節點
list_add(structlist_head *new, struct list_head *head)
list_add_tail(structlist_head *new, sturct list_head *head)
第一個函數在head后面插入一個節點
第二個函數在鏈表尾部插入一個節點
刪除節點:
list_del(structlist_head *entry)
提取數據結構:
list_entry(ptr,type, member)
ptr為已知節點指針ptr,type為節點結構體類型,member為節點指針的type結構體中的名字。返回type結構體的指針。
遍歷:
list for each(structlist_head *ops, struct list_head *head)
從head開始遍歷每個節點,節點指針保存在ops里面。
二、實例
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David?Xie");
MODULE_DESCRIPTION("ListModule");
MODULE_ALIAS("List?module");
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()
{
inti=0;
INIT_LIST_HEAD(&student_list);
pstudent=kmalloc(sizeof(struct?student)*5,GFP_KERNEL);
memset(pstudent,0,sizeof(structstudent)*5);
for(i=0;i<5;i++)
{
sprintf(pstudent[i].name,"Student%d",i+1);
pstudent[i].num=i+1;
list_add(&(pstudent[i].list),?&student_list);
}
list_for_each(pos,&student_list)
{
tmp_student=list_entry(pos,struct?student,list);
printk("<0>student%d?name:?%s\n",tmp_student->num,tmp_student->name);
}
return0;
}
void?mylist_exit()
{
inti?;
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list));
}
kfree(pstudent);
}
module_init(mylist_init);
module_exit(mylist_exit);
總結
以上是生活随笔為你收集整理的linux内核链表使用例,Linux设备驱动工程师之路——内核链表的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 数字不用,oracle –
- 下一篇: linux查看无线网卡频率,查看无线网卡