开发中接触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. 【转】bt协议的详细分析

    转自:https://baoz.net/bt-protocol/ 一 BT系统的组成结构 1 普通的Web服务器:        例如Apache或IIS服务器 2 一个静态的种子文件:     即. ...

  2. Android下得到已安装Application信息

    在上一篇blog中,谈到如何利用APK archive文件得到相应信息.(当时发现例如ProcessName,DataDir等信息,其实是无法得到的). 当前咱们看看如何通过系统取得已经安装的Appl ...

  3. Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)

    [目录] 一.[基础知识——扫盲] 二.[DOM.SAX.JDOM.DOM4j简单使用介绍] 三.[性能测试] 四.[对比] 五.[小插曲XPath] 六.[补充] 关键字:Java解析xml.解析x ...

  4. 学通javaweb 24堂课 学习笔记

    17.01:简单配置控制器 1.一个controller protected ModelAndView handleRequestInternal(HttpServletRequest request ...

  5. 第二次作业第3题_JH

    3.完成小组的“四则运算”项目的需求文档(使用Markdown写文档),尝试同组成员在各自PC上修改同一文档后,如何使用Git命令完成GitHub上的文档的更新,而不产生冲突.并验证GitHub上的文 ...

  6. SQL 学习与工作日常:语句积累

    1.跨服务器连接数据表 --打开服务器配置'Ad Hoc Distributed Queries' --exec sp_configure 'show advanced options',1 --re ...

  7. 【排障】tomact未能看到网页

    [排障]tomact未能看到网页 文:食梦貘 这是几个月前的事情了,那时候我在安装xwiki,需要用到tomcat,但是初次安装好时碰上过一个故障: 安装tomcat后,客户机用IE网址上输入:服务端 ...

  8. 关于Eclipse中的快捷键占用的解决.

    刚进公司用的之前离职员工的电脑,打开Eclipse经常用的一个alt+/ 内容提示快捷键就是不好使. 让同事帮忙之后才发现原因. 在eclipse中快捷键设置是在  windows---->pr ...

  9. 1.2、Mybatis二级缓存测试

    package me.gacl.test; import me.gacl.domain.User; import me.gacl.util.MyBatisUtil; import org.apache ...

  10. 【JDK源码系列】ConcurrentHashMap

    并发永远是高性能的话题,而并发容器又是java中重要的并发工具,所以今天我们来分析一下Concurrent包中ConcurrentHashMap(以下简称Chashmap).普通容器在某些并发情况下的 ...