Linux内核中链表的设计思路

一般实际项目中的链表,节点中存储的数据其实是一个结构体,这个结构体中包含若干的成员,这些成员加起来构成了我们的节点数据区域。

实际上链表操作是相同的,而涉及到数据区域的操作就有不同。

鉴于以上2点,能不能有一种办法把所有链表中操作方法里共同的部分提取出来用一套标准方法实现,然后把不同的部分留着让具体链表的实现者(编程者)自己去处理呢?

Linux内核中链表的设计思路
内核链表中自己实现了一个纯链表(纯链表就是没有数据区域,只有前后向指针)的封装,以及纯链表的各种操作函数(节点创建、插入、删除、遍历······)。这个纯链表本身的用法是给我们具体链表作为核心来调用。
内核中核心纯链表的实现在include/linux/list.h文件中。list.h中实现了一个纯链表的完整封装,包含节点定义和各种链表操作方法。

#include <linux/list.h>

struct driver_info
{
int data;
};

// driver结构体用来管理内核中的驱动
struct driver
{
char name[20]; // 驱动名称
int id; // 驱动id编号
struct driver_info info; // 驱动信息,
struct list_head head; // 内嵌的内核链表成员

分析driver结构体,可知:前三个成员都是数据区域成员(就是我们之前简化为int data的东西),第4个成员是一个struct list_head类型的变量,这就是一个纯链表。

本来driver结构体是没有链表的,也无法用链表来管理。但是driver内嵌的head成员本身就是一个纯链表,所以driver通过head成员给自己扩展了链表的功能。

driver通过内嵌的方式扩展链表成员,本身不只是有了一个链表成员,关键是可以通过利用list_head本身事先实现的链表的各种操作方法来操作head。

最终效果:我们可以通过遍历head来实现driver的遍历;遍历head的函数在list.h中已经事先写好了,所以我们内核中去遍历driver时就不用重复去写了。

通过操作head来操作driver,实质上就是通过操作结构体的某个成员变量来操作整个结构体变量。这里面要借助container_of宏

猜你喜欢

转载自blog.csdn.net/weixin_42325069/article/details/84147612