开发中接触Linux越来越多,休息放松之余,免不了翻看翻看神秘的Linux的内核。看到双向链表时,觉得挺有意思的,此文记下。

作为众多基础数据结构中的一员,双向循环链表在各种“教科书”中的实现是相当的标准和一致的。

大概就是下面这个样子:

 typedef struct node_tag{
//T data;
struct node_tag *prev;
struct node_tag *next;
}node;

当你需要某种类型的链表时,把数据成员之类的往节点里塞就是了。比如菜谱链表,里面就可以有宫爆鸡丁,酸辣粉,地三鲜,水煮鱼,麻辣鸡翅。。。

嗯,当你需要另外一种链表时,接着如法炮制,只要功夫深,几十上百也不是问题。有一部分人善于解决这类问题,它们叫做CP程序员(Copy-Paste),

不要问我为什么知道。C++模板在这点上能实现通用特性,但不在本次内容之列了。

  有着极客精神的Linux,在内核中肯定不会像上面这么做的。内核中有大量的数据结构需要使用双向链表,诸如进程、模块、文件。

难道要人去维护各种类型的双向链表?而且还是不能复用的链表。我想没多少人愿意把时间花在这种事情上吧。维护一种通用的不就好了。

链表节点,作为一个“连接件”,最本质的内容就是把一些对象链接起来,至于对象内部存储的数据,是可以不用知道的。

在include/linux/list.h文件中,就有使用这样的一个"连接件“:

struct list_head {
struct list_head *next, *prev;
};

和node_tag相比,少了数据部分。

list_head作为独立变量时,充当的是链表头的角色;如果作为结构体成员时,则是“连接件”的角色。

  在这样的实现方式下,要获得某种类型的链表,只需在宿主结构中声明一个list_head成员,还可以任意的取名;

关键是,链表操作只需以list_head为对象进行实现;剩下唯一的问题是,在遍历链表时,该如何获取宿主结构的首地址?

毕竟链表是用来装内容用的。这里利用编译器的一个小技巧就可以算出地址偏移

#define offsetof(s,m)   (size_t)&(((s *)0)->m)

有了list_head相对宿主结构首地址的偏移,和自身地址来个加减就可以得到宿主的首地址,接下该怎么操作就怎么操作了。

个人觉得这里面有面向对象的意思。抽取出共同的“连接件” list_head,链表操作也以list_head为对象进行设计,

除了要具体访问操作宿主结构之外,全部都是共性的东西。

Linux内核中的通用双向循环链表的更多相关文章

  1. C语言通用双向循环链表操作函数集

    说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  ...

  2. Linux内核中的算法和数据结构

    算法和数据结构纷繁复杂,但是对于Linux Kernel开发人员来说重点了解Linux内核中使用到的算法和数据结构很有必要. 在一个国外问答平台stackexchange.com的Theoretica ...

  3. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

  4. Linux内核中的GPIO系统之(3):pin controller driver代码分析

    一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...

  5. [翻译] Linux 内核中的位数组和位操作

    目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...

  6. Linux内核中常用的数据结构和算法(转)

    知乎链接:https://zhuanlan.zhihu.com/p/58087261 Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树. 链表 Linux内核代码大量使用了 ...

  7. Linux内核中的软中断、tasklet和工作队列具体解释

    [TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom ...

  8. linux内核中socket的创建过程源码分析(总结性质)

    在漫长地分析完socket的创建源码后,发现一片浆糊,所以特此总结,我的博客中同时有另外一篇详细的源码分析,内核版本为3.9,建议在阅读本文后若还有兴趣再去看另外一篇博文.绝对不要单独看另外一篇. 一 ...

  9. Linux内核中的GPIO系统之(3):pin controller driver代码分析--devm_kzalloc使用【转】

    转自:http://www.wowotech.net/linux_kenrel/pin-controller-driver.html 一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道 ...

随机推荐

  1. Java数据抓取经验【转载】

    本人担任职友集的java工程师五年,其中抓取数据占主要的一部分,抓取的信息只要有两部分,职位和简历,其中职位的抓取量为日均插入量为30万,更新量 为60万,抓取全国300多个人才网站.职友集(现在改名 ...

  2. IOS 图片阴影,圆角等处理

    一直以来,为IOS添加图片的特殊效果都是通过跟美工的配合,比如,要加阴影,就从美工那边获得一张阴影效果图,在界面上画两个UIImageView,将阴影放在下面,图像放上上面,错开一定角度.有比如想做圆 ...

  3. SQL索引详解

    转自:http://www.cnblogs.com/AK2012/archive/2013/01/04/2844283.html SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可 ...

  4. Floating-Info---Android

    https://github.com/alt236/Floating-Info---Android    

  5. 一天JavaScript示例-在功能上的标量参数和数组参数的差异

    <!DOCTYPE> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta h ...

  6. 反射---Java高级开发必须懂的

        理解反射对学习Java框架有很大的帮助,如Spring框架的核心就是使用Java反射实现的,而且对做一些Java底层的操作会很有帮助.  一.Class类的使用         1.万事万物皆 ...

  7. WebGL on iOS8 最终等到了这一天

    WWDC2014刚结束,这次的大会是名符事实上的开发人员大会.更贴切的应该说的确是一次软件开发人员的大会.对于OSX和iOS的很多其它功能特性让人兴奋.Swift新语言促成了如上图片 但我更感兴趣的是 ...

  8. leetcode第一刷_Jump Game

    这个题事实上非常easy的,我一開始想复杂了,它没要求记录路径,事实上仅仅要看一下每一步之后所能延伸到的最远的位置就能够了,在这一个最远位置前面的那些位置,都是能够到达的,假设扫到了某个i,它大于当前 ...

  9. html5中viewport使用

    html5中viewport使用 转载自:http://www.maoegg.com/the-usage-of-viewport-in-html5/ 用html5开发移动应用时往往会遇到手机的分辨率或 ...

  10. 梭子鱼:APT攻击是一盘更大的棋吗?

    随着企业对IT的依赖越来越强,APT攻击可能会成为一种恶意打击竞争对手的手段.目前,APT攻击目标主要有政治和经济目的两大类.而出于经济目的而进行的APT攻击可以获取竞争对手的商业信息,也可使用竞争对 ...