linux 获取链表节点数,LINUX基础-list链表

linux-链表

在看linux内核或者由linux提供的一些代码中,经常会遇到LIST_HEAD、INIT_LIST_HEAD等宏定义,以及一些如list_for_each、list_entry等函数。下面我介绍下常用的几个宏定义以及函数的意义。

1.struct list_head

在linux中用的是双向循环链表,定义的结构如下:

struct list_head

{

struct list_head *next, *prev;

}

注意定义的这个链表节点中是没有数据域的,在linux内核中不是链表结构中包含数据域,而是在数据结构中内嵌链表节点。这个和linux内核中的KObjet等数据结构一样都是内嵌的。

2.初始化linux链表

初始化一个链表就是声明一个节点,让这个节点的prev域和next域都指向它自身。有两种方法:

(1):LIST_HEAD(name);

#define LIST_HEAD_INIT(name) { &(name), &(name) }

#define LIST_HEAD(name) \

struct list_head name = LIST_HEAD_INIT(name)

声明一个节点name ,让这个节点的prev域和next域都指向它自身的地址。

(2):INIT_LIST_HEAD(ptr);

#define INIT_LIST_HEAD(ptr) do { \

(ptr)->next = (ptr); (ptr)->prev = (ptr); \

} while (0)

以上两个没有区别,就是在使用INIT_LIST_HEAD之前要先申明一个list_head变量ptr。

2.遍历一个链表

(1)list_for_each;

#define list_for_each(pos, head) \

for (pos = (head)->next; prefetch(pos->next), pos != (head); \

pos = pos->next)

#define __list_for_each(pos, head) \

for (pos = (head)->next; pos != (head); pos = pos->next)

list_for_each()有prefetch()prefetch() prefetch()用于预取以提高遍历速度,而__list_for_each()无prefetch()用于简单的表的遍历.

(2)list_for_each_safe

for (pos = (head)->next, n = pos->next; pos != (head); \

pos = n, n = pos->next)

这个主要是在遍历的过程中,要删除这个节点是用到。如果在list_for_each中调用list_del(pos)(将pos的前后指针指向undefined state)panic,list_del_init(pos)(将pos前后指针指向自身)导致死循环。

注意list_for_each和list_for_each_safe就是一个for循环,使用的时候注意如果在循环体里面有删除节点是用list_for_each_safe,没有得时候就用list_for_each.

3.list_entry()函数

list_entry函数用于根据链表指针找到包含这个链表指针的数据结构体。

#define list_entry(ptr, type, member) \

container_of(ptr, type, member)

container_of见文章 《LINUX基础-container_of》

4.list_for_each_entry

一般来讲用list_for_each循环遍历以后,就要调用list_entry来获得数据结构体。list_for_each_entry就是上面两个的综合。

#define list_for_each_entry(pos, head, member) \

for (pos = list_entry((head)->next, t ypeof(*pos), member); \

prefetch(pos->member.next), &pos->member != (head); \

pos = list_entry(pos->member.next, typeof(*pos), member))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值