linux双向链表List结构分析

原创 2017年09月13日 17:16:26
双向链表是linux内核中的一个核心数据结构,由于其运用场景众多如task列表、设备列表等等,因此内核将其操作逻辑独立了出来。下面我们以i2c的设备树列表为例来看一下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:链表项在数据结构体中的成员变量名称




版权声明:本文为博主原创文章,未经博主允许不得转载。如本文对您有帮助,欢迎点赞评论。

数据结构:链表(linked-list)

链表分为单向链表(Singly linked lis)、双向链表(Doubly linked list)、循环链表(Circular Linked list)。...
  • juanqinyang
  • juanqinyang
  • 2016年05月09日 11:09
  • 2816

数据结构 《3》----双向链表(带有头节点)

本文参照了 C与指针中双向链表的实现,力求简单明了。 双向链表带有一个头节点,        头节点的pre指针指向链表的最后一个node;        next指向第一个node;        ...
  • u012653791
  • u012653791
  • 2014年01月15日 21:48
  • 2085

数据结构:双向链表实现队列与循环链表

一、双向链表(double linked list)如图26.5,是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。双向链表的基本操作与单链表基本一样,除了插入和删除的时候需要更改两个指针变量...
  • Simba888888
  • Simba888888
  • 2013年04月26日 18:45
  • 4295

Linux利用list_head结构实现双向链表

转自http://www.cnblogs.com/bastard/archive/2012/10/19/2731107.html 通常实现双向链表的数据结构: struct list_...
  • qingkongyeyue
  • qingkongyeyue
  • 2017年07月24日 21:16
  • 143

Linux利用list_head结构实现双向链表

 转自:http://www.cnblogs.com/bastard/archive/2012/10/19/2731107.html 通常实现双向链表的数据结构: struct li...
  • shujuliu818
  • shujuliu818
  • 2016年02月17日 14:24
  • 199

Linux利用list_head结构实现双向链表

通常实现双向链表的数据结构: struct list_node1{ struct list_node1 *next,*prev; type1 m1; type2 m2...
  • jgw2008
  • jgw2008
  • 2016年10月28日 18:39
  • 156

Linux利用list_head结构实现双向链表

通常实现双向链表的数据结构: struct list_node1{ struct list_node1 *next,*prev; type1 m1; type2 m2...
  • taiyuanwuyin
  • taiyuanwuyin
  • 2016年12月15日 08:57
  • 142

深入浅出linux内核源代码之双向链表list_head pdf codes

  • 2010年04月07日 12:13
  • 140KB
  • 下载

深入浅出linux内核源代码之双向链表list_head.pdf

  • 2010年09月10日 19:22
  • 170KB
  • 下载

linux双向链表分析之list_del中的技巧

原文出处z2007b http://blog.csdn.net/z2007b/article/details/6370383。 linux内核的双向链表是比较经典的东西,网上分析链表的同志基本分析了...
  • mznewfacer
  • mznewfacer
  • 2012年03月02日 14:42
  • 2573
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux双向链表List结构分析
举报原因:
原因补充:

(最多只允许输入30个字)