概述
原标题:Linux 通用的双向循环链表(二)
list_entry主要用于从list节点查找其内嵌在的结构。比如定义一个结构struct A{ struct list_head list; }; 如果知道结构中链表的地址ptrList,就可以从ptrList进而获取整个结构的地址(即整个结构的指针) struct A *ptrA = list_entry(ptrList, struct A, list);
这种地址翻译的技巧是linux的拿手好戏,container_of随处可见,只是链表节点多被封装在更复杂的结构中,使用专门的list_entry定义也是为了使用方便
/** * list_first_entry - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. * * Note, that list is expected to be not empty.*/#definelist_first_entry(ptr, type, member) list_entry((ptr)->next, type, member)
list_first_entry是将ptr看完一个链表的链表头,取出其中第一个节点对应的结构地址。使用list_first_entry是应保证链表中至少有一个节点。
/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list.*/#definelist_for_each(pos, head) for(pos = (head)->next; prefetch(pos->next), pos != (head); pos= pos->next)
list_for_each循环遍历链表中的每个节点,从链表头部的第一个节点,一直到链表尾部。中间的prefetch是为了利用平台特性加速链表遍历,在某些平台下定义为空,可以忽略。
/** * __list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. * * This variant differs from list_for_each() in that it's the * simplest possible list iteration code, no prefetching is done. * Use this for code that knows the list to be very short (empty * or 1 entry) most of the time.*/#define__list_for_each(pos, head) for(pos = (head)->next; pos != (head); pos = pos->next)
__list_for_each与list_for_each没什么不同,只是少了prefetch的内容,实现上更为简单易懂。
/** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list.*/#definelist_for_each_prev(pos, head) for(pos = (head)->prev; prefetch(pos->prev), pos != (head); pos= pos->prev)
list_for_each_prev与list_for_each的遍历顺序相反,从链表尾逆向遍历到链表头。
/** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list.*/#definelist_for_each_safe(pos, n, head) for(pos = (head)->next, n = pos->next; pos != (head); pos= n, n = pos->next)
list_for_each_safe 也是链表顺序遍历,只是更加安全。即使在遍历过程中,当前节点从链表中删除,也不会影响链表的遍历。参数上需要加一个暂存的链表节点指针n。
/** * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list.*/#definelist_for_each_prev_safe(pos, n, head) for(pos = (head)->prev, n = pos-> prev; prefetch(pos->prev), pos != (head); pos= n, n = pos->prev)
list_for_each_prev_safe 与list_for_each_prev同样是链表逆序遍历,只是加了链表节点删除保护。
/** * 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.*/#definelist_for_each_entry(pos, head, member) for(pos = list_entry((head)->next, typeof(* pos), member); prefetch(pos->member.next), &pos->member != (head); pos= list_entry(pos->member.next, typeof(*pos), member))
list_for_each_entry不是遍历链表节点,而是遍历链表节点所嵌套进的结构。这个实现上较为复杂,但可以等价于list_for_each加上list_entry的组合。
/** * list_for_each_entry_reverse - iterate backwards 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.*/#definelist_for_each_entry_reverse(pos, head, member) for(pos = list_entry((head)->prev, typeof(* pos), member); prefetch(pos->member.prev), &pos->member != (head); pos= list_entry(pos->member.prev, typeof(*pos), member))
list_for_each_entry_reverse 是逆序遍历链表节点所嵌套进的结构,等价于list_for_each_prev加上list_etnry的组合。
/** * list_for_each_entry_continue - continue iteration 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. * * Continue to iterate over list of given type, continuing after * the current position.*/#definelist_for_each_entry_continue(pos, head, member) for(pos = list_entry(pos->member.next, typeof(* pos), member); prefetch(pos->member.next), &pos->member != (head); pos= list_entry(pos->member.next, typeof(*pos), member))
list_for_each_entry_continue也是遍历链表上的节点嵌套的结构。只是并非从链表头开始,而是从结构指针的下一个结构开始,一直到链表尾部。
/** * list_for_each_entry_continue_reverse - iterate backwards from the given point * @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. * * Start to iterate over list of given type backwards, continuing after * the current position.*/#definelist_for_each_entry_continue_reverse(pos, head, member) for(pos = list_entry(pos->member.prev, typeof(* pos), member); prefetch(pos->member.prev), &pos->member != (head); pos= list_entry(pos->member.prev, typeof(*pos), member))
list_for_each_entry_continue_reverse 是逆序遍历链表上的节点嵌套的结构。只是并非从链表尾开始,而是从结构指针的前一个结构开始,一直到链表头部。
/** * list_for_each_entry_from - iterate over list of given type from the current point * @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. * * Iterate over list of given type, continuing from current position.*/#definelist_for_each_entry_from(pos, head, member) for(; prefetch(pos->member.next), &pos->member != (head); pos= list_entry(pos->member.next, typeof(*pos), member))
list_for_each_entry_from 是从当前结构指针pos开始,顺序遍历链表上的结构指针。
/** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct.*/#definelist_for_each_entry_safe(pos, n, head, member) for(pos = list_entry((head)->next, typeof(* pos), member), n= list_entry(pos->member.next, typeof(* pos), member);&pos->member != (head); pos= n, n = list_entry(n->member.next, typeof(*n), member))
list_for_each_entry_safe 也是顺序遍历链表上节点嵌套的结构。只是加了删除节点的保护。
/** * list_for_each_entry_safe_continue - continue list iteration safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type, continuing after current point, * safe against removal of list entry.*/#definelist_for_each_entry_safe_continue(pos, n, head, member) for(pos = list_entry(pos->member.next, typeof(* pos), member), n= list_entry(pos->member.next, typeof(* pos), member);&pos->member != (head); pos= n, n = list_entry(n->member.next, typeof(*n), member))
list_for_each_entry_safe_continue 是从pos的下一个结构指针开始,顺序遍历链表上的结构指针,同时加了节点删除保护。
/** * list_for_each_entry_safe_from - iterate over list from current point safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry.*/#definelist_for_each_entry_safe_from(pos, n, head, member) for(n = list_entry(pos->member.next, typeof(* pos), member);&pos->member != (head); pos= n, n = list_entry(n->member.next, typeof(*n), member))
list_for_each_entry_safe_from 是从pos开始,顺序遍历链表上的结构指针,同时加了节点删除保护。
/** * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry.*/#definelist_for_each_entry_safe_reverse(pos, n, head, member) for(pos = list_entry((head)->prev, typeof(* pos), member), n= list_entry(pos->member.prev, typeof(* pos), member);&pos->member != (head); pos= n, n = list_entry(n->member.prev, typeof(*n), member))
list_for_each_entry_safe_reverse 是从pos的前一个结构指针开始,逆序遍历链表上的结构指针,同时加了节点删除保护。
至此为止,我们介绍了linux中双向循环链表的结构、所有的操作函数和遍历宏定义。相信以后在linux代码中遇到链表的使用,不会再陌生
嵌入式Linux中文站
最专业的中文嵌入式Linux网站,8年磨剑,注册用户数万人!
分享嵌入式 & Linux技术干货、教程、资讯、高薪职位
分享点击右上角按钮
投稿admin@embeddedlinux.org.cn返回搜狐,查看更多
责任编辑:
最后
以上就是爱笑铃铛为你收集整理的linux单向循环链表,Linux 通用的双向循环链表(二)的全部内容,希望文章能够帮你解决linux单向循环链表,Linux 通用的双向循环链表(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复