`
omygege
  • 浏览: 1353538 次
文章分类
社区版块
存档分类
最新评论

Linux内核学习之链表

 
阅读更多

文章参照任桥位Linux内核修炼之道3.6节编写。

在Linux内核中大量地方使用了链表这个数据结构。相信科班出身的学生或者自己学习过数据结构的同学都不陌生,不错,他就是最简单的线性结构——链表。不过,在内核当中,一般采用的都是循环双联表的数据结构。因为源码有三百多行我就不贴在这里,有兴趣的去下载一下:http://download.csdn.net/detail/huiguixian/3889011

1. 链表的定义

这个跟我们在课本上学习的一样,相当简单。包括了一个前项指针,和后项指针。是不是有点不对劲?不错,竟然没有数据域!不急,我们慢慢看。

没有数据是内核链表的一大特色,因为他采用的方式比较特殊,他不是用链表来包含数据的,而是让数据项反回来包含链表的。刚开始多多少少有点难以理解,下面会解释的。

2. 链表的的定义和初始化

(1)采用LIST_HEAD宏在编译时静态初始化

LIST_HEAD_INIT是宏定义,也就是说在定义的时候把他扩展一下就很容易理解了。比如初始化语句为

LIST_HEAD(event_list),可以理解为

结构体大家应该还没有忘记吧,里面有一条可以按照成员顺序在定义时对其进行初始化,所以这句就很明显了。目的是把next prev指针初始化指向它本身。

(2)采用INIT_LIST_HEAD函数在运行时动态初始化,这个目的一眼就看出来了,同上面一样。

3. 判断链表是否为空的操作,即是判断是否指向自己本身而已

4.插入操作,学过链表操作的都看得懂,看不懂的自己去学链表去。

5. 移动、删除等等类似,主要讲遍历!遍历的精彩部分在于链表是被数据包含着的,如何通过被包含的链表取出包含他的数据(有点拗口)

比如书上举的那个例子:

数据结构是usb_hub,里面包含着一个list_head数据项,然后现在有一个list_head的链表hub_event_list,要取出里面包含hub_event_list.next的数据usb_hub。这就是上述代码的功能。最重要的函数为list_entry,代码如下:

这个不用解释,他调用的是container_of(ptr, type, member),直接看这个宏定义

这个看起来比较费力。需要一步步理解。首先,宏定义不是函数,宏定义的参数不受函数的限制,所以在list_entry和container_of的第二个参数都是以数据类型做参数的。另外GCC有一个对ISO C的扩展,就是他支持typeof操作,具体可以看这里:http://blog.csdn.net/huiguixian/article/details/7045311。主要看最后讲解typeof。简单来看他就是可以返回一个类型,基本可以用在你想用的任何时候。

接着上面的例子来解释:

type为usb_hub,type *就是usb_hub*,0可以理解为NULL,也就是usb_hub->event_list就是((type *)0)->member。一整句就是定义了一个list_head类型的常量指针,指向了参数的event_list。然后下一步是通过计算偏移量,让这个指针减去这个偏移量,即减去后的指针指向的可以看作是一个usb_hub的数据结构,至此就把usb_hub取出来了。

分享到:
评论

相关推荐

    Linux内核双向链表简单分析

    详细的介绍了Linux内核中使用的最频繁的双向链表

    linux内核链表提取与使用

    将linux内核源码中list.h拿出来, 增删与遍历部分写了详细注释, 关于链表合并, 没用过所以没写. 源码版本是2.6.32, 不过链表的源码改动应该不是很大. 我的邮箱2253238252@qq.com, 代码有什么不对的欢迎发邮件给我

    linux内核链表 让你熟悉内核

    剖析linux 内核 linux内核链表

    Linux内核的纯链表代码

    该文件为Linux纯链表的包含文件,为Linux内核的原始代码,部分讲解在我的博客中。可用于学习C指针,链表。配上博客地址:https://blog.csdn.net/weixin_44313435/article/details/104457115

    深入分析Linux内核链表

    对linux内核的链表结构和对内核链表的操作进行超详细讲解

    基于Linux的内核链表源代码

    一、linux内核链表 1、普通链表的数据区域的局限性 之前定义数据区域时直接int data,我们认为我们的链表中需要存储的是一个int类型的数。但是实际上现实编程中链接中的节点不可能这么简单,而是多种多样的。 一般...

    linux内核链表实现

    linux内核链表的实现,包括内核链表的定义,以及内核链表相关的操作

    linux内核链表源代码

    linux内核链表源代码,是list.h是链表的实现,有兴趣的朋友可以下载分析。

    Linux内核中链表和散列表的实现原理揭秘

    Linux内核的实现,大量使用了数据结构,包括了数组、链表和散列表。其中用的最多的是双向循环链表。Linux内核使用的是自己定义的链表和散列表,简单而高效,使用方法也非常的别具一格。 研究Linux内核的链表和散...

    linux下双向循环链表实用例子

    此问linux内核中对链表的双向循环链表进行简单的添加、删除、初始化等基本操作列子,大家可以进行简单的学习

    Linux内核链表移植和测试代码

    Linux内核链表移植和测试代码

    linux内核双向循环链表头文件list.h

    linux内核双向循环链表头文件list.h,免积分下载,希望对你有所帮助!

    linux内核链表与测试代码

    博客详细讲解Linux内核链表,教你看懂Linux内核链表与普通链表有什么不一样,并且有测试代码

    算法学习资料:详解Linux内核之双向循环链表

    算法学习资料:详解Linux内核之双向循环链表

    linux内核链表介绍与了解

    链表是一种常用的组织有序数据的数据结构,它通过指针将一系列数据节点连接成一条数据链,是线性表的一种重要实现方式。相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以...

    抽取linux内核链表模块

    linux内核中有关于list 、kfifo等数据结构的实现,从源码中抽取出list部分,可以在linux应用编程中使用。有详细的抽取过程原理,ubunt12.04上完成

    linux源码内核双向链表文件

    linux 内核双向链表文件,linux内核链表与众不同,不是把将数据结构塞入链表,而是将链表节点塞入数据,Linux内核链表的设计初衷是为了解决不同数据类型作为链表数据节点对函数接口和封装的影响

    Linux内核链表测试

    linux2.4.18版本源码 内核链表 用户态移植 vc6.0下测试

    linux内核链表

    博客详细讲解Linux内核链表,教你看懂Linux内核链表与普通链表有什么不一样

    linux内核链表库

    linux内核链表插入,排序函数库,库里面包含了一些宏。可以进行链表的插入,,删减。与一般链表不同的是,可以连接不同类型的数据。

Global site tag (gtag.js) - Google Analytics