Linux内核中的双循环链表
Linux内核中的双循环链表
2006-11-27 19:14
双循环链表传统实现
在传统的双循环链表实现中,如果创建某种数据结构的双循环链表,通常采用的办法是在这个数据结构的类型定义中加入两个(指向该类型对象的)指针next和prev。例如:
typedef struct foo {
…
struct foo *prev;
struct foo *next;
…
} foo_t;
这里给出了对应的节点结构、空的双循环链表和非空的双循环链表示意图。
Linux内核中双循环链表实现
在linux内核中,有大量的数据结构需要用到双循环链表,例如进程、文件、模块、页面等。若采用双循环链表的传统实现方式,需要为这些数据结构维护各自的链表,并且为每个链表都要设计插入、删除等操作函数。(由于用来维持链表的next和prev指针指向对应类型的对象,因此一种数据结构的链表操作函数不能用于操作其它数据结构的链表。)
在Linux源代码树的include/linux/list.h文件中,采用了一种(数据结构)类型无关的双循环链表实现方式。其思想是将指针prev和next从具体的数据结构中提取处理构成一种通用的"双链表"数据结构list_head,而list_head被作为一个成员嵌入到要拉链的数据结构(被称为宿主数据结构)中。这样,只需要一套通用的链表操作函数就可以将list_head成员作为"连接件",把宿主数据结构链接起来。如下图所示:
在Linux内核中的双循环链表实现方式下:
1. 链表结构作为一个成员嵌入到宿主数据结构内;
2. 可以将链表结构放在宿主结构内的任何地方;
3. 可以为链表结构取任何名字;
4. 宿主结构可以有多个链表结构。
下面我们将基于Linux 2.4.21分析Linux内核双循环链表的实现及应用。
声明和初始化
链表结构定义如下:
struct list_head {
struct list_head *next, *prev;
};
我们可以用struct list_head声明一个链表节点。需要注意的是,Linux 的每个双循环链表都有一个链表头,链表头也是一个节点,只不过它不嵌入到宿主数据结构中,即不能利用链表头定位到对应的宿主结构。
我们可以调用INIT_LIST_HEAD()宏初始化链表节点,将next和prev指针都指向其自身。如果这个节点是链表头,我们就构造了一个空的双循环链表。
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
LIST_HEAD()宏
相关文档:
1、 一些头文件的作用:
<assert.h>:ANSI C。提供断言,assert(表达式)
<glib.h>:GCC。GTK,GNOME的基础库,提供很多有用的函数,如有数据结构操作函数。使用glib只需要包含<glib.h>
<dirent.h>:GCC。文件夹操作函数。struct dirent,struct DIR,opendir(),closedir(),readdir(),readdi ......
1) 工具说明
在SecureCRT这样的ssh登录软件里, 通过在Linux界面里输入rz/sz命令来上传/下载文件. 对于RHEL5, rz/sz默认没有安装所以需要手工安装.
sz: 将选定的文件发送(send)到本地机器;
rz:运行该命令会弹出一个文件选择窗口, 从本地选择文件上传到服务器(receive).
下载安装包lrzsz-0.12.20.tar. ......
参见:http://isis.poly.edu/kulesh/stuff/src/klist/
Introduction:
Linux kernel is mostly written in the C language. Unlike many other languages C does not have
a good collection of data structures built into it or supported by a collection of standard libraries.
Therefore, you're probably excited ......
在Linux操作系统下修改IP、DNS和路由配置
ifconfig eth0 新ip
然后编辑/etc/sysconfig/network-scripts/ifcfg-eth0,修改ip
一、修改IP地址
[aeolus@db1 network-scripts]$ vi ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=219.136.241.211
NETMASK=255.255.255.128
......