Linuxs中常用的数据结构

这篇博客探讨了Linux内核的单内核结构,它结合了宏内核和微内核的优点,允许模块化设计。作者通过一个简单的内核模块编程示例展示了如何在Linux中编写和编译内核代码。此外,还介绍了Linux中的双链表数据结构及其使用,并讲解了快速查找数据的时间复杂度。博客还提到了解决哈希冲突的三种方法,并深入解析了指针偏移量的计算。
摘要由CSDN通过智能技术生成

Linuxs是单内核

在这里插入图片描述

宏内核:把所有东西都集成到内核里,优点:高效 缺点:稳定性差

微内核:内核中只有基本的调度,内存管理等,其他的都是作为用户态守护进程进行运行,模块化程度高,优点:超级稳定 可以kill掉驱动进程 缺点:效率低,进程间同喜消耗资源

Linux是单内核结构:吸收了微内核的优点可以进行模块化设计,支持动态加载内核模块,同时吸收了宏内核的优点把关键模块集中在内核中比较高效

img

Linux内核编程例子

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init lkp_init(void);
static int __exit lkp_exit(void);


static int __init lkp_init(void)
{
printk("<1>Hello ,Word!\n");
return 0;
}

static int __exit lkp_exit(void)
{
printk("<2>Hello,Word exit\n");
}
module_init(lkp_init);
module_exit(lkp_exit);

首先是这个init与exit前面不是一个下划线,而是两个下划线。

而且要注意print后跟的是k,不可以习惯性的打成f了。

img

Makefile编写

obj-m += test.o
CURRENT_PATH:=$(shell pwd)
LINUX_KERNEL:=$(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/kernels/$(LINUX_KERNEL)

all:
        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

这里共有四处是要特别注意的,比较容易犯错的地方。而且如果没有注意到的同学往往自己检查起来也很难查到出错的原因。

首先,obj与-m中间没有空格。

其次,右上角的框框里是你的模块程序的名字后加.o。比如我这里模块程序的名字叫test.c,于是我这里是test.o

接下来,两个make的前面是一个TAB键,绝对不可以使用其他比如空格之类的来在形式上进行替代。

最后,$符号前面与M=之间没有空格,必须紧密相连。

img

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JrwFT574-1631711923934)(C:\Users\zwh\AppData\Roaming\Typora\typora-user-images\image-20210915203434430.png)]


双链表是Linux中的基础数据结构,但是是做了一个list_head的结构体嵌入在各个数据结构中,一开始初始化时next,prev都是指向自己
在这里插入图片描述
在这里插入图片描述

可以使用list_empty来判断链表是非为空 true为空 false为有内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFTIKp5m-1631711878662)(C:\Users\zwh\AppData\Roaming\Typora\typora-user-images\image-20210915204846922.png)]

链表头部插入形成一个栈,尾部插入形成一个队列,static有信息隐藏的作用,只能在本文件中使用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

先看&((type *)0)->member:
把“0”强制转化为指针类型,则该指针一定指向“0”(数据段基址)。因为指针是“type *”型的,所以可取到以“0”为基地址的一个type型变量member域的地址。那么这个地址也就等于member域到结构体基地址的偏移字节数。简单说就是从地址0形成一个type型的结构体指针,找到对应member的地址就是偏移量

再来看 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))):
(char *)(ptr)使得指针的加减操作步长为一字节,(unsigned long)(&((type *)0)->member)等于ptr指向的member到该member所在结构体基地址的偏移字节数。二者一减便得出该结构体的地址。转换为 (type *)型的指针,大功告成。简单说结构体都是放在栈中ptr要比entry的地址大,往上增长
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


hlist是linux内核中关键的数据结构
在这里插入图片描述

时间复杂度O(1)下查到数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJyy7cad-1631711878674)(C:\Users\zwh\AppData\Roaming\Typora\typora-user-images\image-20210915211054721.png)]
解决哈希冲突的三种方法: 开放寻址法 再散列法 链地址法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值