原文:http://blog.csdn.net/lmjjw/article/details/9833025
1 位置
原文:http://blog.csdn.net/lmjjw/article/details/9833025
1 位置
位于./usr/src/linux-2.6.32.9/include/linux/list.h
使用时包括
#include<linux/list.h>
2 数据结构
1
2
3
4
5
6
7
8
9
10
11
12
|
*list_head结构包含两个指向list_head结构的指针prev和next,由此可见,内核的链表具备双链表功能,实际上,通常它都组织成双循环链表。*/
struct
list_head {
struct
list_head *next, *prev;
};
/*头结点结构*/
struct
hlist_head {
struct
hlist_node *first;
};
/*结点结构*/
struct
hlist_node {
struct
hlist_node *next, **pprev;
};
|
3 接口
3.1 offsetof
- 原型
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - 功能
在已知某一个成员变量的名字和结构体类型的情况下,计算该成员相对于结构体的起始地址的偏移量 - 参数
TYPE:结构体类型名称
MEMBER:结构体中成员 - 返回
该成员相对于结构体的起始地址的偏移量。
3.2 container_of
- 原型
#define container_of(ptr, type, member) - 功能
已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。 - 参数
ptr:某一个成员的指针
type:结构体类型
member:成员变量名字
3.3 LIST_HEAD_INIT
- 原型
#define LIST_HEAD_INIT(name) { &(name), &(name); }
- 功能
初始化一个结点名字为name的双向循环链表的头结点 - 参数
name:结点名字
3.4 LIST_HEAD
- 原型
#define LIST_HEAD(name)
- 功能
初始化一个结点名字为name的双向循环链表的头结点 - 参数
name:结点名字
3.5 INIT_LIST_HEAD
- 原型
static inline void INIT_LIST_HEAD(struct list_head *list) - 功能
初始化一个结点名字为name的双向循环链表的头结点
-
参数
list:结点名字
3.6 _list_add
- 原型
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) - 功能
添加结点new到prev和next之间 - 参数
new:新的结点
prev:前一个结点
next:后一个结点
3.7 list_add
- 原型
static inline void list_add(struct list_head *new, struct list_head *head) - 功能
添加结点new到链表头 - 参数
new:新的结点
head:链表头
3.8 list_add_tail
- 原型
static inline void list_add_tail(struct list_head *new, struct list_head *head) - 功能
添加结点new到链表尾 - 参数
new:新的结点
head:链表头
3.9 __list_del
- 原型
static inline void __list_del(struct list_head * prev, struct list_head * next) - 功能
删除结点 - 参数
prev:被删除结点的前驱结点
next:被删除结点后驱结点
3.10 __list_del_entry
- 原型
static inline void __list_del_entry(struct list_head *entry) - 功能
删除结点entry - 参数
entry:被删除结点
3.11 list_del
- 原型
static inline void list_del(struct list_head *entry) - 功能
删除结点entry,将entry的prev指向LIST_POISON1,next指向LIST_POISON2. - 参数
entry:被删除结点 - 说明
指向LIST_POISON不会引起缺页错误。
3.12 list_replace
- 原型
static inline void list_replace(struct list_head *old, struct list_head *new) - 功能
用结点new替换结点old - 参数
new:新结点
old:旧结点
3.13 list_replace_init
- 原型
static inline void list_replace_init(struct list_head *old, struct list_head *new) - 功能
用结点new替换结点old,并初始化old。 - 参数
new:新结点
old:旧结点
3.14 list_del_init
- 原型
static inline void list_del_init(struct list_head *entry) - 功能
删除结点entry,并初始化entry。 - 参数
entry:被删除结点返回
3.15 list_move
- 原型
static inline void list_move(struct list_head *list, struct list_head *head) - 功能
先将list节点从原链表中删除,然后将其添加到head链表的表头 - 参数
list:移除结点
head:链表表头。
3.16 list_move_tail
- 原型
static inline void list_move_tail(struct list_head *list, struct list_head *head) - 功能
先将list节点从原链表中删除,然后将其添加到head链表的表尾 - 参数
list:移除结点
head:链表表头。
3.17 list_is_last
- 原型
static inline int list_is_last(const struct list_head *list, const struct list_head *head) - 功能
测试list节点是否为head链表的表尾节点。是返回1,否则返回0。 - 参数
list:被测试节点
head:链表表头。 - 返回
0或1
3.18 list_empty
- 原型
static inline int list_empty(const struct list_head *head) - 功能
判断head链表是否为空链表,是返回1,否则返回为0; - 参数
head:链表表头。 - 返回
0或1
3.19 list_empty_careful
- 原型
static inline int list_empty_careful(const struct list_head *head) - 功能
判断节点head的前驱和后驱是否都指向head。是返回1,否则返回0. - 参数
head:链表表头。 - 返回
0或1 - 说明
完善 list_empty函数的缺陷。
3.20 list_rotate_left
- 原型
static inline void list_rotate_left(struct list_head *head) - 功能
函数每次将头结点后的一个结点放到head链表的末尾,直到head结点后没有其他结点。 - 参数
head:链表表头。
3.21 list_is_singular
- 原型
static inline int list_is_singular(const struct list_head *head) - 功能
判断head链表是否为单节点链表。是返回1,否为0; - 参数
head:链表表头。 - 返回
0或1
3.22 __list_cut_position
- 原型
static inline void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry) - 功能
这个函数是将head链表的头结点至entry节点之间的节点连在list节点后面,即组成以list节点为头结点的新链表。 - 参数
list:新链表的头结点
head:链表头
entry:节点
3.23 list_cut_position
- 原型
static inline void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry) - 功能
与__list_cut_position功能相似,不过要先判断链表head是否为空链表,再判断是否为了单链表而且节点不是entry的情况,如果head==entry,直接初始化list。 - 参数
list:新链表的头节点
head:链表头
entry:节点
3.24 __list_splice
- 原型
static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next) - 功能
将list链表的全部节点(头节点list除外)插入在prev和next节点之间。 - 参数
list:链表的头节点
prev:前节点
next:后节点
3.25 list_splice
- 原型
static inline void list_splice(const struct list_head *list, struct list_head *head) - 功能
在list是非空链表的情况下,将其插在head链表的头部,即head节点的后面。此函数不安全,因为在插入后还能通过list节点访问到其余的节点。 - 参数
list:链表的头结点
head:头结点
3.26 list_splice_tail
- 原型
static inline void list_splice_tail(struct list_head *list, struct list_head *head) - 功能
在list是非空链表的情况下,将其插在head链表的尾部,即head节点的前面。 - 参数
list:链表的头结点
head:头结点
3.27 list_splice_init
- 原型
static inline void list_splice_init(struct list_head *list, struct list_head *head) - 功能
在list是非空链表的情况下,将其插在head链表的尾部,即head节点的前面。然后对list节点进行初始化,排除不安全因素。 - 参数
list:链表的头结点
head:头结点
3.28 list_splice_tail_init
- 原型
static inline void list_splice_tail_init(struct list_head *list,struct list_head *head) - 功能
在list是非空链表的情况下,将其插在head链表的尾部,即head节点的前面。然后对list节点进行初始化,排除不安全因素。 - 参数
list:链表的头结点
head:头结点
3.29 list_entry
- 原型
#define list_entry(ptr, type, member) - 功能
获取type类型结构体的起始指针 - 参数
ptr:type类型的结构体中member成员的指针
type:结构体类型
member:结构体中成员 - 返回
结构体的起始指针
3.30 list_first_entry
- 原型
#define list_first_entry(ptr, type, member) - 功能
已知type类型的结构体中member成员的指针后,求得它所在的链表的下一个指针所指的member所在的type类型的结构体的起始地址! - 参数
ptr:type类型的结构体中member成员的指针
type:结构体类型
member:结构体中成员 - 返回
结构体的起始地址!
3.31 list_for_each
- 原型
#define list_for_each(pos, head) - 功能
从head节点开始(不包括head节点!)遍历它的每一个节点! - 参数
pos:循环指针
head:链表头
3.32 __list_for_each
- 原型
#define __list_for_each(pos, head) - 功能
从head节点开始(不包括head节点!)遍历它的每一个节点! - 参数
pos:循环指针
head:链表头
3.33 list_for_each_prev
- 原型
#define list_for_each_prev(pos, head) - 功能
它也是从head节点开始(不包括head节点)向前遍历每一个节点!即从链表的尾部开始遍历! - 参数
pos:循环指针
head:链表头
3.34 list_for_each_safe
- 原型
#define list_for_each_safe(pos, n, head) - 功能
从head节点开始(不包括head节点!)遍历它的每一个节点!它用n先将下一个要遍历的节点保存起来,防止删除本节点后,无法找到下一个节点,而出现错误! - 参数
pos:循环指针
n:缓存节点
head:链表头
3.35 list_for_each_prev_safe
- 原型
#define list_for_each_prev_safe(pos, n, head) - 功能
它也是从head节点开始(不包括head节点)向前遍历每一个节点!即从链表的尾部开始遍历! - 参数
pos:循环指针
n:缓存节点
head:链表头
3.36 list_for_each_entry
- 原型
#define list_for_each_entry(pos, head, member) - 功能
已知指向某个结构体的指针pos,以及指向它中member成员的指针head,从下一个结构体开始向后遍历这个结构体链 - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.37 list_for_each_entry_reverse
- 原型
#define list_for_each_entry_reverse(pos, head, member) - 功能
已知指向某个结构体的指针pos,以及指向它中member成员的指针head,从下一个结构体开始向前遍历这个结构体链。 - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.38 list_prepare_entry
- 原型
#define list_prepare_entry(pos, head, member) - 功能
判断pos这个指针是否为空,为空的话给它赋值list_entry(head, typeof(*pos), member)这条语句求出来的结构体的地址! - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.39 list_for_each_entry_continue
- 原型
#define list_for_each_entry_continue(pos, head, member) - 功能
已知指向某个结构体的指针pos,以及指向它中的member成员的head指针,从它的下一个结构体开始向后遍历这个链表。 - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.40 list_for_each_entry_continue_reverse
- 原型
#define list_for_each_entry_continue_reverse(pos, head, member) - 功能
已知指向某个结构体的指针pos,以及指向它中的member成员的head指针,从它的前一个结构体开始向前遍历这个链表。 - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.41 list_for_each_entry_from
- 原型
#define list_for_each_entry_from(pos, head, member) - 功能
从pos节点开始,向后遍历链表。 - 参数
pos:结构体指针
head:链表头
member:结构体成员
3.42 list_for_each_entry_safe
- 原型
#define list_for_each_entry_safe(pos, n, head, member) - 功能
先保存下一个要遍历的节点!从head下一个节点向后遍历链表。 - 参数
pos:结构体指针
n:缓冲节点
head:链表头
member:结构体成员
3.43 list_for_each_entry_safe_continue
- 原型
#define list_for_each_entry_safe_continue(pos, n, head, member) - 功能
先保存下一个要遍历的节点!从pos下一个节点向后遍历链表。 - 参数
pos:结构体指针
n:缓冲节点
head:链表头
member:结构体成员
3.44 list_for_each_entry_safe_from
- 原型
#define list_for_each_entry_safe_from(pos, n, head, member) - 功能
先保存下一个要遍历的节点!从pos节点向后遍历链表。 - 参数
pos:结构体指针
n:缓冲节点
head:链表头
member:结构体成员
3.45 list_for_each_entry_safe_reverse
- 原型
#define list_for_each_entry_safe_reverse(pos, n, head, member) - 功能
先保存下一个要遍历的节点!从链表尾部向前遍历链表。 - 参数
pos:循环结构体指针
n:缓冲节点
head:链表头
member:结构体成员
3.46 list_safe_reset_next
- 原型
#define list_safe_reset_next(pos, n, member) - 功能
获取n结构体指针 - 参数
pos:循环结构体指针
n:缓冲节点
member:结构体成员
3.47 HLIST_HEAD_INIT
- 原型
#define HLIST_HEAD_INIT { .first = NULL } - 功能
初始化hlist头结点
3.48 HLIST_HEAD
- 原型
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } - 功能
初始化名为name的hlist头节点 - 参数
name:头结点名字
3.49 INIT_HLIST_HEAD
- 原型
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) - 功能
初始化头节点指针ptr - 参数
ptr:头结点指针
3.50 INIT_HLIST_NODE
- 原型
static inline void INIT_HLIST_NODE(struct hlist_node *h) - 功能
初始化hlist节点 - 参数
h:需要初始化的节点
3.51 hlist_unhashed
- 原型
static inline int hlist_unhashed(const struct hlist_node *h) - 功能
判断h->pprev是否为空,是返回1,否返回0; - 参数
h :hlist_node节点 - 返回
1或0
3.52 int hlist_empty
- 原型
static inline int hlist_empty(const struct hlist_head *h) - 功能
判断hlist是否为空,是返回1,否返回0; - 参数
h:hlist_head类型节点 - 返回
0或1
3.53 __hlist_del
- 原型
static inline void __hlist_del(struct hlist_node *n) - 功能
删除结点n; - 参数
n:被删除结点
3.54 hlist_del
- 原型
static inline void hlist_del(struct hlist_node *n) - 功能
删除结点n,将结点next、pprev分别指向LIST_POISON1、LIST_POISON2。这样设置是为了保证不在链表中的结点项不能被访问。 - 参数
n:被删除结点
3.55 hlist_del_init
- 原型
static inline void hlist_del_init(struct hlist_node *n) - 功能
先判断结点是否为空,不为空删除,再初始化节点。 - 参数
n:被删除结点
3.56 hlist_add_head
- 原型
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) - 功能
增加结点n到h表头。 - 参数
n:被添加的节点
h:hlist表头
3.57 hlist_add_before
- 原型
static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) - 功能
增加结点n到结点next之前。 - 参数
n:被添加的节点
next:节点
3.58 hlist_add_after
- 原型
static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next) - 功能
增加结点n到结点next之后。 - 参数
n:节点
next:新节点
3.59 hlist_add_fake
- 原型
static inline void hlist_add_fake(struct hlist_node *n) - 功能
设置n->pprev = &n->next。 - 参数
n:结点
3.60 hlist_move_list
- 原型
static inline void hlist_move_list(struct hlist_head *old, struct hlist_head *new) - 功能
头结点new接管头结点old的所有节点,并初始化old。 - 参数
old:头结点
new:头结点
3.61 hlist_entry
- 原型
#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - 功能
已知某一个成员变量的名字、指针和结构体类型的情况下,计算结构体的指针,也就是计算结构体的起始地址。 - 参数
ptr:type类型的结构体中member成员的指针
type:结构体类型
member:结构体中成员
3.62 hlist_for_each
- 原型
#define hlist_for_each(pos, head) - 功能
遍历hlist链表 - 参数
pos:循环指针
head:链表头
3.63 hlist_for_each_safe
- 原型
#define hlist_for_each_safe(pos, n, head) - 功能
遍历hlist链表,一般在删除结点使用。 - 参数
pos:循环指针
n:缓存指针
head:链表头
3.64 hlist_for_each_entry
- 原型
#define hlist_for_each_entry(tpos, pos, head, member) - 功能
遍历找typeof(*tpos)的结构体类型入口地址 - 参数
tpos:类型的指针类型的循环变量,也就是真正的值
pos:循环链表的变量
head:表头
member:成员
3.65 hlist_for_each_entry_continue
- 原型
#define hlist_for_each_entry_continue(tpos, pos, member) - 功能
从结点pos下一个遍历找typeof(*tpos)的结构体类型入口地址 - 参数
tpos:类型的指针类型的循环变量,也就是真正的值
pos:循环链表的变量
head:表头
member:成员
3.66 hlist_for_each_entry_from
- 原型
- #define hlist_for_each_entry_from(tpos, pos, member)
- 功能
从节点pos开始遍历找typeof(*tpos)的结构体类型入口地址
- 参数
tpos:类型的指针类型的循环变量,也就是真正的值
pos:循环链表的变量
member:成员
3.67 hlist_for_each_entry_safe
- 原型
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) - 功能
从头节点head开始遍历找typeof(*tpos)的结构体类型入口地址 - 参数
tpos:类型的指针类型的循环变量,也就是真正的值
pos:循环链表的变量
head:表头
member:成员
4 示例说明
4.1 示例1
验证offsetof计算偏移量、container_of寻找入口地址、LIST_HEAD_INIT初始化结构体。
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
typedef
struct
node
{
int
age;
int
score;
int
num;
}student;
int
main()
{
/*计算偏移量*/
int
offset=offsetof( student,num);
printf
(
"offset is %d \n"
,offset);
/*寻找入口地址*/
student *temp = (student*)
malloc
(
sizeof
(student));
if
(NULL==temp)
return
;
student *entry=container_of(&temp->score,student,score);
printf
(
"temp add is %x \n"
,temp);
printf
(
"entry add is %x \n"
,entry);
/*初始化结构体*/
struct
list_head name = LIST_HEAD_INIT(name);
printf
(
"name add is %x \n"
,name.next);
printf
(
"name.next add is %x \n"
,name.next);
printf
(
"name.prev add is %x \n"
,name.prev);
return
0;
}
|
打印结果:
offset is 8
temp add is 8b85008
entry add is 8b85008
name add is bf897598
name.next add is bf897598
name.prev add is bf897598