linux双向链表List结构分析
来源:互联网 发布:数据可视化的产品目标 编辑:程序博客网 时间:2024/05/18 18:15
双向链表是linux内核中的一个核心数据结构,由于其运用场景众多如task列表、设备列表等等,因此内核将其操作逻辑独立了出来。下面我们以i2c的设备树列表为例来看一下List列表的使用方法。
2,在i2c_dev结构体中嵌入了list_head结构体,使用list结构体成员来连接这个i2c设备链表。
当从list_head中找到指定的list结构体成员后,再使用list_entry确定其i2c_dev结构体的起始地址。
3,以i2c_dev_list为链表头,使用list_add_tail向i2c_dev链表中添加各个list项。其中&i2c_dev->list即为新加项
4,使用list_del即可将&i2c_dev->list项从链表中删除
5,list_for_each_entry提供的是一个for循环,使用时实现其中的循环体即可。
我们在i2c_dev中使用list_for_each_entry遍历链表找出其中数据结构体中nr成员满足条件的选项。
解释一下list_for_each_entry的几个参数
i2c_dev:游标指针,依次返回数据结构体的首地址
i2c_dev_list:链表首项
list:链表项在数据结构体中的成员变量名称
如图所示,双向链表不包含任何数据,在使用时,将其嵌入到目标结构体中使用。且第一个list_head不与数据机构体关联,作为整个链表的起始。
List的实现代码在kernel\include\linux\list.h中,部分常用函数、宏如下:
#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)static inline void INIT_LIST_HEAD(struct list_head *list){list->next = list;list->prev = list;}/** * list_entry - get the struct for this entry * @ptr:the &struct list_head pointer. * @type:the type of the struct this is embedded in. * @member:the name of the list_struct within the struct. */#define list_entry(ptr, type, member) \container_of(ptr, type, member)void list_add_tail(struct list_head *new, struct list_head *head);void list_del(struct list_head *entry);/** * list_for_each_entry-iterate over list of given type * @pos:the type * to use as a loop cursor. * @head:the head for your list. * @member:the name of the list_struct within the struct. */#define list_for_each_entry(pos, head, member)\for (pos = list_first_entry(head, typeof(*pos), member);\ &pos->member != (head);\ pos = list_next_entry(pos, member))
我们以i2c设备对List的使用为例代码位于kernel/drivers/i2c/i2c-dev.c
static LIST_HEAD(i2c_dev_list);struct i2c_dev {struct list_head list;struct i2c_adapter *adap;struct device *dev;};list_add_tail(&i2c_dev->list, &i2c_dev_list);list_del(&i2c_dev->list);list_for_each_entry(i2c_dev, &i2c_dev_list, list) {if (i2c_dev->adap->nr == index)goto found;}1,使用LIST_HEAD定义了一个首list_head
2,在i2c_dev结构体中嵌入了list_head结构体,使用list结构体成员来连接这个i2c设备链表。
当从list_head中找到指定的list结构体成员后,再使用list_entry确定其i2c_dev结构体的起始地址。
3,以i2c_dev_list为链表头,使用list_add_tail向i2c_dev链表中添加各个list项。其中&i2c_dev->list即为新加项
4,使用list_del即可将&i2c_dev->list项从链表中删除
5,list_for_each_entry提供的是一个for循环,使用时实现其中的循环体即可。
我们在i2c_dev中使用list_for_each_entry遍历链表找出其中数据结构体中nr成员满足条件的选项。
解释一下list_for_each_entry的几个参数
i2c_dev:游标指针,依次返回数据结构体的首地址
i2c_dev_list:链表首项
list:链表项在数据结构体中的成员变量名称
阅读全文
1 1
- linux双向链表List结构分析
- linux 内核分析之list_head 双向链表结构
- Linux 内核中双向链表及list.h 文件分析
- 线性表(List)---链式存储结构(双向链表)
- 双向链表list
- Linux内核双向循环链表分析
- linux内核部件--通用双向链表list
- linux内核部件--通用双向链表list
- Linux利用list_head结构实现双向链表
- Linux利用list_head结构实现双向链表
- Linux利用list_head结构实现双向链表
- Linux利用list_head结构实现双向链表
- List-c双向链表
- List双向链表容器
- List双向链表容器
- 双向循环链表list
- List (双向链表)
- list双向链表容器
- poj 3250 Bad Hair Day(单调栈)
- c标签 if else c标签 总结
- MYSQL数据库将 表1的字段值更改为表2字段的值
- [BZOJ2815][ZJOI2012]灾难(倍增lca+top)
- 【git】将代码放到远程仓库
- linux双向链表List结构分析
- [Usaco2014 Mar]Sabotage(dp)
- 设计模式原则----里氏替换原则,依赖倒置原则
- 关于mysql中LOAD DATA LOCAL INFILE指定列
- 设置linux环境下ftp权限
- SpringMVC核心技术
- .net中两种弹窗提示
- 面试题47. 不用加减乘除做加法
- 配置搭建阿里云服务器nginx+uwsgi (python)