设为首页 加入收藏

TOP

Linux内核中的通用双向循环链表
2015-04-07 15:29:58 来源: 作者: 【 】 浏览:28
Tags:Linux 内核 通用 双向 循环

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


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


大概就是下面这个样子:


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Maven项目的目录结构 下一篇Java采用3种方式判断用户输入的字..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: