栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux带头双向循环链表,linux内核循环,内核链表分析

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux带头双向循环链表,linux内核循环,内核链表分析

上节我们对Linux内核链表的设计原理进行分析,理解了内核链表的设计的优点,并解决内核链表访问问题。

linux内核链表之HashList内核链表之HashList哈希链表(HashList/hlist)的设计初衷是为了方便快捷的查找,为了降低Hash表中键的冲突,一般设计会将Hash桶的数量设计的比较大。Linux链表设计者认为常规的双指针头结点的双向循环链表设计对于大数量桶的Hash表过于浪费,从而设计一套适合于Hash表的只有单指针的表头。该表头只有指向首节点的指针,没有指向尾节点指针,从而在海量Hash表中能够将表头存储空间减少一半。Hash链表这种单头指针设计缺失了对尾结点的时间复杂度的O(1)访问。同样也带来了对不同类..https://blog.csdn.net/xuedaon/article/details/121653851本节我们主要将Linux内核中链表的实现库进行分析解释。

// 内核链表数据结构
struct list_head{
	struct list_head *next, *prev;
};

// 初始化内核链表头节点: 头结点的next,prev指针都指向自己的地址
#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;
}

 

 图 1 初始化链表头节点

// 将new节点插入到prev之后,next之前
static inline void __list_add(struct list_head *new, struct list_head *prev,  struct list_head *next)
{
	next->prev = new;		// 如图2:(1)
	new->next = next;		// 如图2:(2)
	new->prev = prev;		// 如图2:(3)
	prev->next = new;		// 如图2:(4)
}
// 将new节点插入到头结点之后
static inline void list_add(struct list_head *new, struct list_head *head)
{
	__list_add(new, head, head->next);
}
// 将new节点插入到头结点之前
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
	__list_add(new, head->prev, head);
}

图 2 新节点插入

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	entry->next = LIST_POISON1;
	entry->prev = LIST_POISON2;
}

 

图 3 链表节点删除

#define list_entry(ptr, type, member) 
	container_of(ptr, type, member)

// 从头到尾遍历整个链表
#define list_for_each(pos, head) 
	for (pos = (head)->next; pos != (head); pos = pos->next)

// 尾从到头遍历整个链表
#define list_for_each_prev(pos, head) 
	for (pos = (head)->prev; pos != (head); pos = pos->prev)

// 安全的从头到尾遍历整个链表:在遍历的时候可以安全的删除节点
#define list_for_each_safe(pos, n, head) 
	for (pos = (head)->next, n = pos->next; pos != (head); 
		pos = n, n = pos->next)

// 安全的从尾到头遍历整个链表:在遍历的时候可以安全的删除节点
#define list_for_each_prev_safe(pos, n, head) 
	for (pos = (head)->prev, n = pos->prev; 
	     pos != (head); 
	     pos = n, n = pos->prev)

// 从头到尾遍历整个链表,并用type *pos指针获取节点的首地址
#define list_for_each_entry(pos, head, member)				
	for (pos = list_entry((head)->next, typeof(*pos), member);	
	     &pos->member != (head); 	
	     pos = list_entry(pos->member.next, typeof(*pos), member))

// 从尾到头遍历整个链表,并用type *pos指针获取节点的首地址
#define list_for_each_entry_reverse(pos, head, member)			
	for (pos = list_entry((head)->prev, typeof(*pos), member);	
	     &pos->member != (head); 	
	     pos = list_entry(pos->member.prev, typeof(*pos), member))
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/679267.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号