数据结构链表之企业级应用-Linux内核双向链表实战

        各位未来的高级程序员好久不见,好久没有更新数据结构和算法了。差点忘记这一方面的实战才是我的强项。那么我们就来上点猛料,有些人干了三年的开发可能都不知道的神奇用法-Linux内核双向链表。这名字一听就很高大上,相信各位已经摩拳擦掌,按捺不住了。那么我们废话不多说,赶紧发车。

在数据结构中,有两种最基础的数据结构,一种是顺序结构,一种是链式结构。这两种结构都非常的重要。我们称之为顺序表和链表。其中链表区分有头链表,无头链表,单链表,双向链表,循环链表等。那么Linux内核中使用的是无头双向链表,其中区别于普通的双向链表。那么内核的双向链表到底是怎么玩的呢?别急,我们先来对比一下传统的双向链表:

typedef struct  _DoubleList

{

        void *data;       //数据域

        struct _DoubleList *last;   //下一个指针域

        struct _DoubleList *front;  //上一个指针域

}DoubleList;    //双向链表基本结构体

如上所示,我们普通的双向链表其实就长这样,一个数据域,两个指针域。数据域用来搭载数据,指针域用来连接上一个节点和下一个节点。对于老C程序员来说手写链表其实并不难,可以说是平平无奇,那么Linux内核的链表究竟优秀在哪里呢?对比我们上述的普通双向链表有何强大的地方?

我们接下来揭晓谜底,请看如下结构体:

typedef struct _LinuxList

{

        struct _LinuxList *next;            //下一个指针域

        struct _LinuxList *front;           //上一个指针域

}LinuxList,LinuxNode;

怎么样?是不是很惊讶,这就是传说中的内核双向链表?平平无奇,甚至还有点简单?高端的东西往往不在于形,而在于使用。那么需要怎么使用这个内核链表呢?

实际上,Linux内核的双向链表是利用了数据与承载数据的结构分离的模式,所以才会设计成这个样子,那么这个模式是怎么样的呢?知其然知其所以然,那么请看下图:

快递大家都知道吧?快递内的物品是主体,而快递外面那层打包盒,就是我们的载体。现在就有人要问了,这个跟我们的链表有什么关系呢?别急,关系非常大。一般情况下,如果以快递公司为视角来看,快递一旦发出,外面那层包装盒是不是就无法进行第二次利用了?相当于把快递盒送给了物品的主人,这样的关联性太强了,对于我们商业代码来说,有一个准则,高内聚,低耦合。那么数据与数据结构的关联性过强,实际上也是不利的。

那么我们的Linux内核双向链表是怎么做的呢?来,请看下图:

怎么样?看起来是不是很像火车的样子,装货的火车就是这种结构。这个结构的优点在于,数据和载体只有依赖关系,而不是共存亡。有点像UML中的聚合关系,那么到此为止,是不是有个大概的概念了呢?所以这么才能达到图中的效果呢?请看如下结构体:

typedef struct  _Star

{

        int radius;

        int colour;

        int x;

        int y;

}Star;

上面是一个星星的结构体,里面包含了星星部分属性,包含了半径,坐标,颜色亮度等。如果我们需要做一个星空的话,那么就需要大量的星星变量。这里或许有人疑问了,可以直接使用数组啊,为什么还要使用链表呢?那么请大家思考一下,如果其中的星星会随着亮度的减弱而慢慢消失的话,那么是不是还需要对内存进行回收呢?如果不进行回收的话,那么已经使用完毕的内存放着岂不是造成了资源的浪费?这对一个高级程序员来说是致命的。

那么我们怎么使用这个内核的双向链表呢?其实很简单,如下所示:

typedef struct _Star

{

        int radius;

        int colour;

        int x;

        int y;

        LinuxNode *n;

}Star;

这样就能达到我说的效果了,但是有人会问,虽然看起来像是车厢一样,但是访问链表没办法访问结构体变量吧?在C语言中有一个宏,offsetof(type, member-designator),其中第一个参数是结构体类型,第二个是结构体类型中的成员变量。那么这个是什么意思呢?实际上就是计算字节偏移数,计算出结构体的成员变量与结构体顶端的字节偏移。

那么有了这个宏之后呢,就可以完美解决找不到结构体对象内存地址的问题了,但是请注意,由于LinuxNode*n结构体成员变量是指针,所以使用的时候一定要搞清楚内存,必须掌握熟练二级指针的水平,否则玩不来的。

最后,大家可以试一下,看看能不能玩起来,如果玩不起来的话可以评论区讨论一下,我会统一做解答,我是程序员玉无涯,一位资深程序员,我们下次见。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值