【linux内核】链表

前言

重点介绍linux使用的链表,其他几种看图简单理解,linux 链表采用数据和链表分开形式的环形双向链表。
本次实验采用linux下模块注册的形式进行,注册后会把链表数据打印到终端。

常用的链表有:

  • 单向链表
    在这里插入图片描述
  • 双向链表
    在这里插入图片描述
  • 环形链表
    在这里插入图片描述

创建基本结构数据

这里使用和内核一样的方法,将链表和数据分开
以下所有的实验 数据都是num ,在测试过程中会不断改变num 的值,通过观察num判断每个节点:

struct list_num
{
    struct list_head list; // 内核链表类型
    int num;
};

linux 链表类型定义:

struct list_head {
	struct list_head *next, *prev;
};

linux链表初始化

内核链表初始化会把头节点地址传到 prev 和 next 成员,
以下有两种方法初始化:

  • 第一种是自定义链表并初始化
  • 第二种是内核主动定义链表并初始化

方法1

    list1.num = 1;
    INIT_LIST_HEAD(&list1.list);

运行结果:
初始化后 prev 和 next 地址相等,都是当前节点。
在这里插入图片描述

方法2

直接调用宏定义:

static LIST_HEAD(list);

linux链表添加节点

添加节点2 和 3, 新增节点采用入栈形式,先进后出,后进新出, 也就是新加的节点作为链表头,
可通过序号 1 和 2 、3 的地址来判断:
在这里插入图片描述

    list1.serial_num = 1;
    INIT_LIST_HEAD(&list1.list); // 节点1
    
    list2.serial_num = 2;
    list_add(&list2.list, &list1.list); // 节点2

    list3.serial_num = 3;
    list_add(&list3.list, &list1.list); // 节点3

运行结果:
在这里插入图片描述

linux链表删除节点

注意删除节点只是从链表上取出来,并不代表清空所占内存

  • 直接清空:
    将删除上述添加的 链表2节点
    list_del(&list2.list);
    list2.serial_num = 0;

运行结果:
链表2的prev、next 地址被清空,链表1和3链接
在这里插入图片描述

  • 清空并且初始化:
    清空并初始化是方便后续可以再使用起来,而且初始化是将自己的节点地址给prev、next指针。
    运行结果:
    在这里插入图片描述

获取链表所在数据结构的基地址 list_entry

如下图,内核大部分链表声明不会是第一个成员,这就导致从其他节点访问时不能直接. 或者 -> 访问, 必须获取基地址才行,这时 list_entry 就有作用了。
在这里插入图片描述

在这里插入图片描述
如下程序片段,第一个例子是错误示范,第二个是正确使用。

    printk("通过list1 访问list2 , 测试 list entry : \r\n");
    printk("错误使用 , 原因是链表的位置不在结构体起始位置 : \r\n");
    //p1 = list_entry( list1.list.prev, struct list_num , list);
    p1 = &list1.list.prev;
    printk("serial_num: %d, addr: %p, prev: %p, next: %p \r\n",p1->serial_num , &p1->list, p1->list.prev , p1->list.next);
    
    printk("正确使用 : \r\n");
    p1 = list_entry( list1.list.prev, struct list_num , list);
    printk("serial_num: %d, addr: %p, prev: %p, next: %p \r\n",p1->serial_num , &p1->list, p1->list.prev , p1->list.next);
    

运行结果:
在这里插入图片描述

结束

源码若有需要私信!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值