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)的首指针.

时间: 2024-10-13 22:53:44

Linux内核-链表的相关文章

Linux 内核链表

一 . Linux内核链表 1 . 内核链表函数 1.INIT_LIST_HEAD:创建链表 2.list_add:在链表头插入节点 3.list_add_tail:在链表尾插入节点 4.list_del:删除节点 5.list_entry:取出节点 6.list_for_each:遍历链表 2.程序代码

例说Linux内核链表(二)

链表使用 我认为熟悉内核链表功能最好的方法就是看一些简单的实例,实例是一个非常好的素材去更好的理解链表. 下面是一个例子,包含创建,添加,删除和遍历链表. <span style="font-size:14px;"><span style="color:#330099;">#include <stdio.h> #include <stdlib.h> #include "list.h" struct

Linux 内核 链表 的简单模拟(2)

接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each(pos, head) for (pos = (head)->next; pos != (head);

例说Linux内核链表(一)

介绍 众所周知,Linux内核大部分是使用GNU C语言写的.C不同于其他的语言,它不具备一个好的数据结构对象或者标准对象库的支持.所以可以借用Linux内核源码树的循环双链表是一件很值得让人高兴的事. 在include/linux/list.h文件中用C实现了一个好用的循环链表.它是有效而且易于操作的,否则它也不会被内核使用(译者注:在kernel中大量的使用了循环双链表结构,比如在在进程描述符实体中我们就可以看到很多struct list_head的身影).不管何时,依靠这种结构,在内核中都

例说Linux内核链表(三)

经常使用的linux内核双向链表API介绍 linux link list结构图例如以下: 内核双向链表的在linux内核中的位置:/include/linux/list.h 使用双向链表的过程,主要过程包括创建包括struct link_head结构的结构体(item),建立链表头.向链表中加入item(自己定义数据结构.双向链表数据单元).删除链表节点.遍历链表,判空等. 1.建立自己定义链表数据结构 struct kool_list{ int to; struct list_head li

linux内核链表的使用

linux内核链表:链表通常包括两个域:数据域和指针域.struct list_head{struct list_head *next,*prev;};include/linux/list.h中实现了一套精彩的链表数据结构.传统的链表指针指向下一个节点的头部.linux链表指针指向下一个指针list_head结构(*next),双向循环.不会随着外部数据的变化而变化,使它具有通用性.? -------------------------------------------------------

linux内核链表的移植与使用

一.  Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /*********************************** 文件名:kernel link list of linux.h 作者:Bumble Bee 日期:2015-1-31 功能:移植linux内核链表 ************************************/ /*链表结点数据结构*/ struct lis

Linux 内核链表使用举例

链表数据结构的定义很简洁: struct list_head { struct list_head *next, *prev; }; list_head结构包含两个指向list_head结构的指针prev和next,该内核链表具备双链表功能,通常它都组织成双循环链表,这里的list_head没有数据域.在Linux内核链表中,不是在链表结构中包含数据,而是在数据结构中包含链表节点.下面是一个简单的内核模块的例子,包含了对链表进行插入.删除.遍历的一些函数: list.c: #include <l

链表的艺术——Linux内核链表分析

引言: 链表是数据结构中的重要成员之中的一个.因为其结构简单且动态插入.删除节点用时少的长处,链表在开发中的应用场景许多.仅次于数组(越简单应用越广). 可是.正如其长处一样,链表的缺点也是显而易见的.这里当然不是指随机存取那些东西,而是因为链表的构造方法(在一个结构体中套入其同类型指针)使得链表本身的逻辑操作(如添加结点,删除结点,查询结点等),往往与其应用场景中的业务数据相互混杂.这导致我们每次使用链表都要进行手工打造,做过链表的人肯定对此深有了解. 是否能将链表从变换莫測的业务数据中抽象出

linux内核链表使用

原文链接:http://blog.csdn.net/xnwyd/article/details/7359373 Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p,如下: struct A{ int property; struct list_head p; } 其中,list_head结构类型定义如下: struct list_head { struct list_head *next,*prev; };