Linux内核-链表

Posted 小凉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核-链表相关的知识,希望对你有一定的参考价值。

 linux内核链表的定义(定义了双向链表,不含数据域)

定义在 /linux-source-3.13.0/include/linux/types.h 头文件中.

1 struct list_head {
2         struct list_head *next, *prev;
3 };

我们可以利用这个数据结构定义含有数据域的链表,如:

1 struct my_list
2 {
3         void * mydata;   //void * 可以指向任何类型的数据
4         struct list_head list;  //隐藏了链表指针
5 } 

 链表的声明和初始化宏(list.h)

定义在 /linux-source-3.13.0/include/linux/list.h 中.

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

初始化一个名为name的双向链表的头节点.(name.pre = &name , name.next = &name)

1 #define LIST_HEAD(name) 2         struct list_head name = LIST_HEAD_INIT(name)

通过调用LIST_HEAD,来声明和初始化一个自己的链表头,产生一个空链表.如:LIST_HEAD(mylist_head)

 

 在链表添加一个节点

定义在 /linux-source-3.13.0/include/linux/list.h 中

具体实现:

 1 /*
 2  * Insert a new entry between two known consecutive entries.
 3  *
 4  * This is only for internal list manipulation where we know
 5  * the prev/next entries already!
 6  */
 7 #ifndef CONFIG_DEBUG_LIST
 8 static inline void __list_add(struct list_head *new,
 9                               struct list_head *prev,
10                               struct list_head *next)
11 {
12         next->prev = new;
13         new->next = next;
14         new->prev = prev;
15         prev->next = new;
16 }
17 #else
18 extern void __list_add(struct list_head *new,
19                               struct list_head *prev,
20                               struct list_head *next);
21 #endif
22 
23 /**
24  * list_add - add a new entry
25  * @new: new entry to be added
26  * @head: list head to add it after
27  *
28  * Insert a new entry after the specified head.
29  * This is good for implementing stacks.
30  */
31 static inline void list_add(struct list_head *new, struct list_head *head) //在head节点后插入new节点,循环链表没有首尾,head可以是任意节点
32 {
33         __list_add(new, head, head->next);
34 }
35 
36 /**
37  * list_add_tail - add a new entry
38  * @new: new entry to be added
39  * @head: list head to add it before
40  *
41  * Insert a new entry before the specified head.
42  * This is useful for implementing queues.
43  */
44 static inline void list_add_tail(struct list_head *new, struct list_head *head) //在head节点前插入new节点
45 {
46         __list_add(new, head->prev, head);
47 }

 遍历链表

定义在 /linux-source-3.13.0/include/linux/list.h 中

1 /**
2  * list_for_each        -       iterate over a list
3  * @pos:        the &struct list_head to use as a loop cursor.
4  * @head:       the head for your list.
5  */
6 #define list_for_each(pos, head) 7         for (pos = (head)->next; pos != (head); pos = pos->next)

 它实际上是一个for循环,利用传入的pos作为循环变量,从表头开始逐顶向后(next方向)移动pos,直至回到head.

 

1 /**
2  * list_entry - get the struct for this entry
3  * @ptr:        the &struct list_head pointer.
4  * @type:       the type of the struct this is embedded in.
5  * @member:     the name of the list_struct within the struct.
6  */
7 #define list_entry(ptr, type, member) 8         container_of(ptr, type, member)

list_entry宏:从结构体(type)某成员变量(menber)指针(prt)来求出该结构体(type)的首指针.

以上是关于Linux内核-链表的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核链表

《Linux内核设计与实现》读书笔记- 内核数据结构

Linux 内核 内存管理RCU 机制 ④ ( RCU 模式下更新链表项 list_replace_rcu 函数 | 链表操作时使用 smp_wmb() 函数保证代码执行顺序 )

Linux--内核链表

例说Linux内核链表

Linux内核-链表