主要内容

  • 链表
  • 队列
  • 映射
  • 二叉树

1. 链表

  • 单向链表、双向链表
  • 环形链表

linux内核中的链表使用方法和一般数据结构中定义的链表是有所不同的。
传统链表:

传统双向链表.png

传统的链表有个最大的缺点就是不好共通化,因为每个node中的data1,data2等等都是不确定的(无论是个数还是类型)。
linux中的链表巧妙的解决了这个问题,linux的链表不是将用户数据保存在链表节点中,而是将链表节点保存在用户数据中。
linux的链表节点只有2个指针(pre和next),这样的话,链表的节点将独立于用户数据之外,便于实现链表的共同操作。

Linux内核链表:

linux内核双向链表.png

最大的问题在于,怎样通过链表的节点来取得用户数据?
答案是通过container_of()宏

#define container_of(ptr, type, member) ({          \const typeof(((type *)0)->member)*__mptr = (ptr);    \(type *)((char *)__mptr - offsetof(type, member)); })
  • type一般是个结构体,也就是包含用户数据和链表节点的结构体。
  • ptr是指向type中链表节点的指针
  • member则是type中定义链表节点是用的名字

比如:

struct student
{int id;char* name;struct list_head list;
};
  • type是struct student
  • ptr是指向stuct list的指针,也就是指向member类型的指针
  • member就是 list

下面分析一下container_of宏:

// 步骤1:将数字0强制转型为type*,然后取得其中的member元素
((type *)0)->member  // 相当于((struct student *)0)->list// 步骤2:定义一个临时变量__mptr,并将其也指向ptr所指向的链表节点
const typeof(((type *)0)->member)*__mptr = (ptr);// 步骤3:计算member字段距离type中第一个字段的距离,也就是type地址和member地址之间的差
// offset(type, member)也是一个宏,定义如下:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)// 步骤4:将__mptr的地址 - type地址和member地址之间的差
// 其实也就是获取type的地址

步骤1,2,4比较容易理解,下面的图以sturct student为例进行说明步骤3:

  1. 首先需要知道 ((TYPE *)0) 表示将地址0转换为 TYPE 类型的地址
  2. 由于TYPE的地址是0,所以((TYPE *)0)->MEMBER 也就是 MEMBER的地址和TYPE地址的差,如下图所示:

理解步骤3.png

2. 队列

FIFO,没啥好说的

  • 队列的size在初始化时,始终设定为2的n次方
  • 使用队列之前将队列结构体中的锁(spinlock)释放

3. 映射

类似于python里的字典
散列表是一种映射,但自平衡二叉树搜索树也能实现存储数据,比如C++中map就是红黑树嘛,在最坏情况下能有更好的表现
Linux内核中的映射叫idr,目标是映射一个位于id标识数UID到一个指针

4. 红黑树

5. 算法复杂度

大o符号代表上限(更差情况)
大θ符号代表最小上限

文末给大家分享几个Linux内核的视频讲解:

1、linux内核,进程调度器的实现,完全公平调度器 CFS:https://www.bilibili.com/video/BV1hf4y1B7Yg/

2、 Linux内核丨红黑树 | 设计模式与算法:https://www.bilibili.com/video/BV1ig4y1v7So/

3、Linux内核学习视频来啦,这么学,才简单:https://www.bilibili.com/video/BV1m54y127Mb/

附上一份Linux内核学习大纲:

Linux内核设计与实现——内核数据结构相关推荐

  1. Linux内核设计与实现---内核同步方法

    内核同步方法 1 原子操作 原子整数操作 原子性与顺序性的比较 原子位操作 2 自旋锁 自旋锁是不可递归的 其他针对自旋锁的操作 自旋锁和下半部 3 读-写自旋锁 4 信号量 创建和初始化信号量 使用 ...

  2. 赵晨雨:从文件系统的数据结构看Linux内核设计

    作者简介 赵晨雨:西安邮电大学2018级陈莉君教授研究生,天真无邪小白一枚,已经爱上linux内核而不能自拔,正在成长为内核狂热爱好者? 跟随陈老师学习linux内核两个月了,对linux内核产生了极 ...

  3. 《Linux内核设计与实现》读书笔记 - 目录 (完结)

    读完这本书回过头才发现, 第一篇笔记居然是 2012年8月发的, 将近一年半的时间才看完这本书(汗!!!). 为了方便以后查看, 做个<Linux内核设计与实现>读书笔记 的目录: < ...

  4. 读《Linux内核设计与实现》我想到了这些书

          从题目中可以看到,这篇文章是以我读<Linux内核设计与实现>而想到的其他我读过的书,所以,这篇文章的主要支撑点是<Linux内核>.       开始读这本书已经 ...

  5. 读 Linux内核设计与实现 我想到了这些书

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴!     ...

  6. Linux内核设计与实现学习笔记目录

    **注:**这是别人的笔记,我只是把目录抄过来 <Linux内核设计与实现学习笔记> 1.<Linux内核设计与实现>读书笔记(一)-内核简介 2.<Linux内核设计与 ...

  7. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块

    本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...

  8. 《Linux内核设计与实现》读书笔记(十二)- 内存管理

    内核的内存使用不像用户空间那样随意,内核的内存出现错误时也只有靠自己来解决(用户空间的内存错误可以抛给内核来解决). 所有内核的内存管理必须要简洁而且高效. 主要内容: 内存的管理单元 获取内存的方法 ...

  9. 《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理

    系统中有很多与时间相关的程序(比如定期执行的任务,某一时间执行的任务,推迟一段时间执行的任务),因此,时间的管理对于linux来说非常重要. 主要内容: 系统时间 定时器 定时器相关概念 定时器执行流 ...

最新文章

  1. Node.js:路由
  2. 弯曲传传感器 WWW.TE.COM
  3. 以下关于python自动化运维错误的是_Python在自动化运维时经常会用到的方法
  4. 中国太阳能热水器市场营销模式探析与品牌格局调研报告2022版
  5. CBA Opportunity Fiori应用的getEntitySet实现
  6. 机房内综合布线电缆的紧密捆绑有哪些问题?
  7. Blazor带我重玩前端(五)
  8. Flask框架从入门到精通之参数配置(二)
  9. JAVA零碎要点011---使用Java操作wkhtmltopdf实现Html转PDF
  10. 2020级C语言大作业 - 小球进框
  11. 关于黑苹果耳机麦克风无法正常输入输出以及VoodooHDA启动慢 解决方法
  12. python窗口居中_Tkinter窗口在屏幕居中的问题
  13. Qt界面无法切换输入法的解决方法
  14. 使用Cytoscape 的BinGO插件绘制GO通路关系图
  15. 阿里大S,强推,接口测试之必会接口加密类型
  16. 你知道吗?火狐搜集您的数据?
  17. React 18的基本使用
  18. 安利 3 个 pandas 数据探索分析神器!
  19. php使用composer安装目录,Composer基本安装与使用
  20. 百度技术沙龙第33期回顾:推荐引擎实战(含资料下载)

热门文章

  1. 助力教育共同富裕,网易云信发布「1+1+N」互联互通解决方案
  2. 致力颠覆豪华智能纯电品牌,高合汽车的底气来自哪?
  3. 聊天机器人的发展史-资料转载与收集
  4. python手机解释器_用Python实现一个Python解释器
  5. 3年级计算机教案,3年级计算机教案.doc
  6. 地籍cad的lisp程序大集合_AutoCAD-LISP程序100例
  7. 如何使用 msiexec.exe 手动删除 VirusScan Enterprise 8.x
  8. 公司成立三年即上市 网游速度获资本垂青
  9. Evernote 快捷键
  10. 一文彻底弄懂单例模式(Singleton)