内核链表
来源:互联网 发布:oppo怎么改4g网络设置 编辑:程序博客网 时间:2024/05/22 11:35
在Linux内核中使用了大量的链表结构来组织数据。这些链表大多采用了[include/linux/list.h]中实现的一套精彩的链表数据结构。
链表数据结构的定义:
struct list_head
{
struct list_head *next, *prev;
};
list_head结构包含两个指向list_head结构的指针prev和next,由此可见,内核的链表具备双链表功能,实际上,通常它都组织成双向循环链表
Linux内核中提供的链表操作主要有:
初始化链表头
INIT_LIST_HEAD(list_head *head)
插入节点
list_add(structlist_head *new, struct list_head *head)
list_add_tail(structlist_head *new, struct list_head *head)
删除节点
list_del(structlist_head *entry)
提取数据结构
list_entry(ptr, type, member) <=> #define list_entry(link, type, member) \
((type *)((char *)(link)-(unsigned long)(&((type *)0)->member)))
已知数据结构中的节点指针ptr,找出数据结构,
遍历
list_for_each(struclist_head *pos, struclist_head *head);
<=>#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
注意在编程时 list_entry与list_for_each的第一个形式参数都必须为指针,因为这两个式子为宏定义展开后是指针的形式,
所以只能定义为指针结构,同样list_entry 返回值的值类型为指针类型。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/list.h>
struct student{
unsigned char name[12];
unsigned int num;
struct list_head list;
};
struct student *pstudent;
struct student *p_stud;
struct list_head head;
struct list_head *pos;
static int hello_init(void)
{
// extern int myprintk();
// myprintk();
int i;
INIT_LIST_HEAD(&head);
pstudent = kzalloc(sizeof(struct student) * 5, GFP_KERNEL);
for(i = 0; i < 5; i++)
{
sprintf(pstudent[i].name,"student%d",i + 1);
pstudent[i].num = i;
list_add_tail(&(pstudent[i].list),&head);
}
list_for_each(pos,&head)
{
p_stud = list_entry(pos,struct student,list);
printk("p_stud->name = %s, p_stud->num = %d\n",p_stud->name , p_stud->num);
}
printk("************************hello world ! ***************************");
return 0;
}
static void hello_exit(void)
{
int i;
for(i = 0; i < 5; i++)
{
list_del(&(pstudent[i].list));
printk("pstudint[%d].list is delete!\n",i);
}
printk(KERN_ALERT"*******************in hello Goodbye world************************\n");
}
module_init(hello_init);
module_exit(hello_exit);
~
链表数据结构的定义:
struct list_head
{
struct list_head *next, *prev;
};
list_head结构包含两个指向list_head结构的指针prev和next,由此可见,内核的链表具备双链表功能,实际上,通常它都组织成双向循环链表
Linux内核中提供的链表操作主要有:
初始化链表头
INIT_LIST_HEAD(list_head *head)
插入节点
list_add(structlist_head *new, struct list_head *head)
list_add_tail(structlist_head *new, struct list_head *head)
删除节点
list_del(structlist_head *entry)
提取数据结构
list_entry(ptr, type, member) <=> #define list_entry(link, type, member) \
((type *)((char *)(link)-(unsigned long)(&((type *)0)->member)))
已知数据结构中的节点指针ptr,找出数据结构,
遍历
list_for_each(struclist_head *pos, struclist_head *head);
<=>#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
注意在编程时 list_entry与list_for_each的第一个形式参数都必须为指针,因为这两个式子为宏定义展开后是指针的形式,
所以只能定义为指针结构,同样list_entry 返回值的值类型为指针类型。
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/list.h>
struct student{
unsigned char name[12];
unsigned int num;
struct list_head list;
};
struct student *pstudent;
struct student *p_stud;
struct list_head head;
struct list_head *pos;
static int hello_init(void)
{
// extern int myprintk();
// myprintk();
int i;
INIT_LIST_HEAD(&head);
pstudent = kzalloc(sizeof(struct student) * 5, GFP_KERNEL);
for(i = 0; i < 5; i++)
{
sprintf(pstudent[i].name,"student%d",i + 1);
pstudent[i].num = i;
list_add_tail(&(pstudent[i].list),&head);
}
list_for_each(pos,&head)
{
p_stud = list_entry(pos,struct student,list);
printk("p_stud->name = %s, p_stud->num = %d\n",p_stud->name , p_stud->num);
}
printk("************************hello world ! ***************************");
return 0;
}
static void hello_exit(void)
{
int i;
for(i = 0; i < 5; i++)
{
list_del(&(pstudent[i].list));
printk("pstudint[%d].list is delete!\n",i);
}
printk(KERN_ALERT"*******************in hello Goodbye world************************\n");
}
module_init(hello_init);
module_exit(hello_exit);
~
0 0
- Linux内核之—内核链表
- 内核部件之内核链表
- Linux嵌入式 -- 内核 - 内核链表
- Linux 内核开发 - 内核链表
- Zephyr OS 内核篇: 内核链表
- linux内核学习:内核链表
- 【内核数据结构】 内核链表分析
- linux内核链表
- linux内核链表
- Linux内核链表
- linux内核链表
- linux内核链表
- 内核链表
- Linux内核链表
- linux内核链表
- 内核链表
- Linux内核链表
- linux内核链表
- ImageView 点击效果 selector 设置
- 根域名匹配正则
- Hdu-3926 Hand in Hand(同构图)
- Erlang 督程 启动和结束子进程
- eclipse恢复默认界面设置和恢复默认快捷键设置
- 内核链表
- 关于素数
- Change the author of a commit in Git
- [ldd] start
- Agile-Scrum
- 微软 WPC 2014 合作伙伴keynote
- 系统哲学
- MySQL表锁定一系列问题;(转载自多处)
- reviewboard-使用RBtools工具提交review申请,提示more files in your changeset has history scheduled with commit.