linux内核链表---挑战常规思维
一.普通链表
1.一般教材上的链表定义如下:
struct node{
int content;
node *next;
};
它将指针域放在链表节点中,上一个节点指针域中的值指向下一个节点的首地址,以此将a1,到an这n个在内存地址中分布不连续的值连接起来,构成顺序表。

2.链表作为一种数据结构,自然需要为它实现一些函数,比如插入节点,搜索和删除节点等,用来维护它的数据集。
(1).创建链表 node *create(...){...}
(2).插入节点 node *insert(...){...}
(3).删除节点 node *delete(...){...}
...
3.如果在一个程序中需要使用两种类型的链表,如下所示
struct node1{
int data;
node1 *next;
};
struct node2{
int data;
node2 *next;
};
那么当我们在定义它们各自的操作的时候,就需要为每个链表各自定义一套方法。比如说创建链表的操作:
node1 *create(...){...};
node2 *create(...){...};
这样就大大增加了代码量,并且较多的指针操作容易带来隐患。
二. linux的内核链表
链表在linux内核中是很常用的数据结构,在进程管理,内存管理等很多地方都有使用。比如著名的task_struct就是用链表组织的。在这样一个使用很多链表的系统中,为每个链表定义自己的一套方法是不现实的。因此使用了一种统一的组织形式。
1.内核链表定义
struct list_head{
struct list_head *next,*prev;
};
它是一个不含数据域的节点,用来将含有数据域的节点“串”起来。
2.一个例子如下
struct my_struct{
int data;
list_head *mylist;
};
如果用它创建一个节点
struct my_struct first = {
.data = 10,
.mylist = LIST_HEAD_INIT(first.mylist)
} ;
创建四个节点并对节点中的数据成员和链表节点成员进行初始化,如下图所示

可以看到,这种组织形式将节点链域与数据域分离开来,节点中的mylist域的作用就是将各个分离的节点穿起来,而mylist使用统一的list_head类型,对链表进行操作时只需要修改节点中的mylist域,而与整个结构体的类型无关,这样就不需要为每一个链表都定义一套自己的操作函数。
为了更好地理解内核链表的优点,画为如下的形式,可以当数据域是附着在list_head类型的节点域上的,将数据域与指针域分离。当我要增加或删除节点时,只需要改动节点中的指针域即可,而这样的指针就像一根线,如果在系统中只有一种线,那么就只需要定义一套链表操作函数

三.总结
书本上的知识一般只是讲述原理,技巧性的东西不会涉及太多。在实际应用中,可能一般的套路是行不通的。linux内核中的链表的实现,的确让人觉得是极为精巧的设计。不仅能大大减少代码量,还方便维护。
linux内核链表---挑战常规思维的更多相关文章
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- C语言 Linux内核链表(企业级链表)
//Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> ...
- 深入分析 Linux 内核链表--转
引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...
- Linux 内核链表
一 . Linux内核链表 1 . 内核链表函数 1.INIT_LIST_HEAD:创建链表 2.list_add:在链表头插入节点 3.list_add_tail:在链表尾插入节点 4.list_d ...
- 深入分析 Linux 内核链表
转载:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/ 一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指 ...
- Linux 内核 链表 的简单模拟(2)
接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the & ...
- Linux 内核 链表 的简单模拟(1)
第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct stu ...
- linux内核链表的移植与使用
一. Linux内核链表为双向循环链表,和数据结构中所学链表类似,具体不再细讲.由于在内核中所实现的函数十分经典,所以移植出来方便后期应用程序中的使用. /********************* ...
- [国嵌攻略][108][Linux内核链表]
链表简介 链表是一种常见的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...
随机推荐
- Spring 基于Java的Bean声明
Spring 基于Java的Bean声明 使用@Configuration进行设置: Xml: <?xml version="1.0" encoding="UTF- ...
- spring EL表达式,null-safe表达式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://ww ...
- 关于flash擦除的方法
一般的Flash,只允许写时将1变成0,而不允许0变成1:仅当擦除时将0变成1.所以写全0xff是没什么意义的 以前对flash只能进行一次写很困惑,这句话解释了原因. norflash就是 对bit ...
- KB奇遇记(10):终章
本来还想写一篇关于前CIO的著名言论,不过想想还是算了.博客空间宝贵,不乱恶心人了. 这篇博文是本系列<KB奇遇记>的最后一篇了. 虽然在KB公司有这么多的苦,但毕竟收获也很多,至少让我懂 ...
- Hadoop权威指南:HDFS-目录,查询文件系统,删除文件
Hadoop权威指南:HDFS-目录,查询文件系统,删除文件 [TOC] 目录 FileSystem实例提供了创建目录的方法 public boolean mkdirs(Path f) throws ...
- [JQuery]JQuery选择器引擎Sizzle
写代码过程中,发现使用JQuery选择器时,$('div.tooltip')和$('.tooltip')的结果不一样,怀疑和选择器的代码逻辑有关(事后证明是代码的低级错误,但是从查找原因的过程中,学到 ...
- 学习计划(一)——JavaScript
一:与前端之缘 大一时除了上课和社团外不知道要学点什么,但是又不想睡觉打游戏,常常就是啥都想学,photoshop,premiere,After Effects都学,但始终没有明确的目标. 大二时一直 ...
- Web Worker无阻塞UI的牛逼技术,html5,可惜无法敢于UI
众所周知,JavaScript是单线程的,JS和UI更新共享同一个进程的部分原因是它们之间互访频繁,但由于共享同一个进程也就会造成js代码在运行的时候用户点击界面元素而没有任何响应这样的情况,这么糟糕 ...
- 丘吉尔,最后一次演讲-Never Give Up
丘吉尔一生最精彩的演讲,也是他最后一次演讲.在剑桥大学的一次毕业典礼上,整个会堂有上万个学生,他们正在等待丘吉尔的出现.正在这时,丘吉尔在他的随从陪同下走进了会场并慢慢走向讲台,他脱下他的大衣交给随从 ...
- Java中abstract和interface的区别
abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力. abstract class和inte ...