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

Linux内核设计基础(八)之内核数据结构

阅读更多

我个人比较喜欢学习数据结构,而Linux内核中实现的数据结构会是我们去学习、理解和应用数据结构的一个很好途径。这里介绍内核中广泛应用的四种数据结构:链表、队列、映射和二叉树。


链表:

Linux内核讲求高效精简,所以有时需要我们动态去创建和分配内存,这时就要借助链表,我们根据实际情况分配内存后,只需修改链表的指针,仍能索引到刚分配的内存区。链表分单向链表、双向链表和循环链表。

  • 单向链表
struct list_element {
	void *data;
	struct list_element *next; /* 指向下一个元素的指针 */
};

  • 双向链表
struct list_element {
	void *data;
	struct list_element *next; /* 指向下一个元素的指针 */
	struct list_element *prev; /* 指向前一个元素的指针 */
};

  • 循环链表
链表最后一个元素的next指针不为NULL,而是指向链表首元素。循环链表中也分单向和双向。


因为循环双向链表提供了最大的灵活性(没有具体例子的对比,暂时还看不出来,希望懂的朋友们留下评论:),所以Linux内核的标准链表就是采用循环双向链表。
另外,如果需要随机访问数据,一般不使用链表,使用链表的理想情况是需要遍历所有数据或需要动态加入和删除数据时。
不过Linux内核中的链表可不像上面例子那样简单和原始,它不是将数据结构塞入链表,而是将链表节点塞入数据结构。
struct list_head {
	struct list_head *next;
	struct list_head *prev;
};

其实这就是所谓的链表节点,那它是如何塞入数据结构的呢?当然是作为数据结构的成员:
struct fox {
	unsigned long tail_length;
	unsigned long weight;
	bool is_fantastic;
	struct list_head list;  /* 所有fox结构体形成链表 */
};

也就是list不再是指向一个fox结构体,而是用.next和.prev指向前后两个list_head结构体。真奇怪,这样的话我们需要知道所指向的两个list_head结构体分别属于哪两个fox结构体,这需要借助宏container_of(),这样我们可以找到这个list_head结构体的父结构(也就是所属的fox结构体)中包含的任何变量。为什么要这样构造链表,希望懂的朋友们留下评论:)

队列:

在内核编程中,我们经常遇到生产者——消费者模型,这时队列是最理想的数据结构,生产者将数据放入队列,消费者则随后取出,先到先得。

映射:

映射指的是一种做法:有一个由唯一键组成的集合,每个键关联一个特定的值,由键得到值得这种关系我们称之为映射。
但用什么数据结构来实现,一般采用散列表(Hash)和自平衡二叉搜索树。也许散列表是我们最熟悉的,构造散列函数,输入唯一键,得到对应值。但其实更多的时候采用二叉树,Linux内核就是如此。
Linux内核中用idr维护一个自定义的映射,用

int idr_get_new(struct idr *idp, void *ptr, int *id);

将id(键)和ptr(值)的映射注入到idr中。而查找操作如下:

void *idr_find(struct idr *idp, int id);

根据id找到对应的指针ptr。

二叉树:

具体红黑树的介绍参见我的博文

红黑树(RED-BLACK TREES)基本概念

内核中每个i节点都有自己的rbtree,以关联在文件中的页偏移,这是红黑树在Linux中的一个应用。





分享到:
评论

相关推荐

    《linux内核注释》

    《Linux内核注释》旨在给程序员和学生提供比以前更详细和更易理解的Linux内核代码注 释。作者分析了核心代码,并对重要的函数、系统调用和数据结构提供了大量的注释。 对《注释》系列丛书的写作灵感都来源于John...

    疯狂内核之——Linux虚拟内存

    2.2.1 数据结构 66 2.2.2 块分配 67 2.2.3 块释放 69 2.3 Linux页面级内存管理 72 2.3.1 分配一组页面 73 2.3.2 释放一组页面 80 2.4 每CPU页面高速缓存 81 2.4.1 数据结构 81 2.4.2 通过每CPU 页高速缓存分配页面 ...

    Linux内核注释

    《Linux内核注释》旨在给程序员和学生提供比以前更详细和更易理解的Linux内核代码注释。作者分析了核心代码,并对重要的函数、系统调用和数据结构提供了大量的注释。 对《注释》系列丛书的写作灵感都来源于John ...

    浅谈Linux内核开发之PCI设备驱动

    本文内容包括:PCI介绍Linux内核对PCI的支持总结参考资料本文介绍了PCI的基本概念,并从Linux内核的角度出发,介绍了PCI设备的初始化以及配置。PCI介绍随着计算机应用的不断更新和发展(比如百兆网卡、视屏流等),...

    Linux服务器监测命令及CPU、硬盘、内存状态命令

    系统让你可以和内核内部数据结构进行交互,获取 有关进程的有用信息,在运行中 (on the fly) 改变设置 (通过改变内核参数)。 与其他文件系统不同,/proc 存在于内存之中 而不是硬盘上。不用重新启动而去看 CMOS ,就...

    ARM_Linux启动分析.pdf

    init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程(进程)空 间内加载init程序,它的进程号是1。 init程序需要读取/etc/inittab文件作为其行为指针,inittab是以行为单位的描述性(非执行性)...

    基于Linux 的防火墙技术研究

    1 基于Linux 的防火墙技术研究 ...基于安全数据结构的防火墙[J]计算机科学,2001(8):56~60 5 作者简介(Author’s brief introduction): 1、宋文功(1966-),男,汉族,硕士(Male. Master.)。中南大学网络中心,工程师...

    LINUX系统管理白皮书

    本书同时收录了Linux领域两位领导人物的作品—相当于“Linux 文档项目”的一个印刷版本,展示了Linux 核心概念及其基本结构。对于面向所有主流Linux子系统的支持与管理任务,本书都进行了恰到好处的讲解。涵盖的主题...

    智能网关结构.docx

    Linux内核采用模块化的组织结构,通过增减内核模块的方式来增减系统的功能,正确合理地设置内核的功能模块,只编译系统所需功能的代码,以获得更高的运行速度。 装载文件系统(file system)。嵌入式系统一般不具备...

    Zynq FPGA 上的 Rocket 芯片

    目标应用程序(RISC-V 二进制文件)将在火箭芯片运行的任何内核之上运行。由riscv-gcc或riscv-llvm编译。 RISC-V Kernel(代理内核或RISC-V Linux)运行在火箭芯片之上。代理内核非常轻量级,设计用于与 Newlib ...

    操作系统内核.zip

    操作系统之最内核部分,通常运行在最高特权级,负责提供基础性、结构性的功能。 3、支承库(亦作“接口库”) 是一系列特殊的程序库,它们职责在于把系统所提供的基本服务包装成应用程序所能够使用的编程接口(API...

    安装 SUSE Linux Enterprise Server --服务器版

    本简明手册提供了对安装 SUSE Linux Enterprise Server 的快速介绍。它是对应 用程序各个字段以及 SUSE Linux Enterprise Server 支持的每个平台的安装类型 的概述,以及对安装过程的简短的说明。 SUSE Linux ...

    入门学习Linux常用必会60个命令实例详解doc/txt

    要想真正理解Linux系统,就必须从Linux命令学起,通过基础的命令学习可以进一步理解Linux系统。 不同Linux发行版的命令数量不一样,但Linux发行版本最少的命令也有200多个。这里笔者把比较重要和使用频率最多的命令...

    Linux操作系统.zip

    操作系统之最内核部分,通常运行在最高特权级,负责提供基础性、结构性的功能。 3、支承库(亦作“接口库”) 是一系列特殊的程序库,它们职责在于把系统所提供的基本服务包装成应用程序所能够使用的编程接口(API...

    嵌入式Linux系统移植步步通

    2.1.2 Linux操作系统 .......................................................................................................8 2.1.3 目标板最后运行的环境....................................................

    操作系统与Linux.zip

    操作系统之最内核部分,通常运行在最高特权级,负责提供基础性、结构性的功能。 3、支承库(亦作“接口库”) 是一系列特殊的程序库,它们职责在于把系统所提供的基本服务包装成应用程序所能够使用的编程接口(API...

Global site tag (gtag.js) - Google Analytics