【Linux】内核中的链表

在这里插入图片描述

🔥博客主页:PannLZ
🎋系列专栏:《Linux系统之路》
🥊不要让自己再留有遗憾,加油吧!


文章目录

    • 链表
      • 1.创建和初始化
      • 2.创建节点
      • 3.添加节点
      • 4.删除节点
      • 5.遍历


链表

内核开发者只实现了循环双链表,因为这个结构能够实现FIFO和LIFO,并且内核开发者要保持最少代码。为了支持链表,代码中要添加的头文件是<linux/list.h>

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

Struct list_head用在链表头和每个节点中。在内核中,将数据结构表示为链表之前,该结构必须嵌入struct list_head字段。

struct car {int door_number;char *color;char *model;struct list_head list; /*内核的表结构 */
};

1.创建和初始化

1).动态方法

动态方法由struct list_head组成,用INIT_LIST_HEAD宏初始化:

struct list_head mylist;
INIT_LIST_HEAD(&mylist);static inline void INIT_LIST_HEAD(struct list_head *list)
{list->next = list;list->prev = list;
}

2).静态方法

静态分配通过LIST_HEAD宏完成:

LIST_HEAD(mylist)#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)#define LIST_HEAD_INIT(name) { &(name), &(name)}
//这为name字段内的每个指针(prev和next)赋值,使其指向name自身(就像INIT_LIST_HEAD做的那样)。

补充:

关于宏中的“\”:\ 的部分,这是 C 语言中的行连接符,也被称为续行符。如果宏的定义超过一行,我们可以使用 \ 来表示该宏的定义还未结束,下一行仍然是该宏的一部分。

2.创建节点

要创建新节点,只需创建数据结构实例,初始化嵌入在其中的list_head字段。以汽车为例,其代码如下:\

struct car *blackcar = kzalloc(sizeof(struct car), GFP_KERNEL);
/* 非静态初始化,因为它是嵌入的列表字段*/
INIT_LIST_HEAD(&blackcar->list);

3.添加节点

内核提供的list_add用于向链表添加新项,它是内部函数__list_add的包装:

void list_add(struct list_head *new, struct  list_head *head);
static inline void list_add(struct list_head*new, struct list_head *head)
{__list_add(new, head, head->next);
}static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}//头插//添加两辆车,类似栈
list_add(&redcar->list, &carlist);
list_add(&blue->list, &carlist);void list_add_tail(struct list_head *new, structlist_head *head);//尾插//添加两辆车,类似队列
list_add_tail(&redcar->list, &carlist);
list_add_tail(&blue->list, &carlist);

4.删除节点

void list_del(struct list_head *entry);//删除红色车
list_del(&redcar->list);

list_del断开指定节点的prev和next指针,移除该节点。分配给该节点的内存需要使用kfree手动释放。

5.遍历

使用宏list_for_each_entry(pos, head, member)进行链表遍历。

  • head:链表的头节点head可以是链表的头节点或任意一项,这没关系,因为所处理的是双向链表
  • member:数据结构(在我们的例子中,它是list)中链表struct list_head的名称。
  • pos:用于迭代。
struct car *acar; /* 循环计数器,用于迭代*/
int blue_car_num = 0;
/* list是数据结构中的list_head结构的名称 */
list_for_each_entry(acar, carlist, list)
{if(acar->color == "blue")blue_car_num++;
}

为什么list_for_each_entry需要传入链表struct list_head的名称呢?请看下面

#define list_for_each_entry(pos, head, member)\
for (pos = list_entry((head)->next,typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next,typeof(*pos), member))#define list_entry(ptr, type, member) \
container_of(ptr, type, member)

鉴于此,我们可以理解这都是container_of的功能。
关于container_of的功能可能可以阅读我关于它的笔记。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/679930.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1. pick gtk dll 程序的制作

文章目录 前言预览细节要点初始窗口尺寸提示音快速提示信息对话框AlertDialog鼠标移入移出事件布局与父子控件关系图片 后续源码及资源 前言 在之前的打包测试中我提到了需要一个挑选dll的程序于是我打算用Gtk来制作这个程序 预览 细节要点 初始窗口尺寸 只有主窗口有set_d…

基于无线传感器网络的LC-DANSE波束形成算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1LC-DANSE算法原理 4.2 LCMV算法原理 5.完整程序 1.程序功能描述 在无线传感器网络中&#xff0c;通过MATLAB对比LC-DANSE波束形成算法和LCMV波束形成算法。对比SNR&#xff0c;mse等指标…

Java中的IO介绍

本章内容 一 、File概念 File可以代表一个目录或者一个文件&#xff0c;并不能代表文件的内容 文件和流的区别&#xff1a;File关注的是文件本身的特征&#xff0c;如名称、路径、修改时间、大小。 流关注的是文件的内容。 二、File基本的操作 常见构造方法 | File(String p…

以用户为中心,酷开科技荣获“消费者服务之星”

在企业顺应消费升级的道路中&#xff0c;企业自身不仅要着力强化对于消费者服务意识的提升&#xff0c;并且要树立诚信自律的行业示范带头作用&#xff0c;助力消费环境稳中向好&#xff0c;不断满足人民群众对美好生活的期待。企业的发展需要消费者的认可&#xff0c;酷开科技…

常见的单片机及其功能

在当今电子技术快速发展的时代&#xff0c;单片机作为核心组件&#xff0c;在各类电子项目和产品中扮演着至关重要的角色。它们的应用范围从简单的家用电器控制到复杂的工业自动化系统&#xff0c;几乎无处不在。接下来&#xff0c;我们将以轻松的语言&#xff0c;探讨几种广泛…

放大器设计

目录 简介单阶段放大器:低噪声放大器例题例题2例题3简介 放大器能够放大信号,是电路设计中不可或缺的一种重要软件。根据应用和结构的不同,可以将放大器分为三类。 小信号:设计目标是在输入输出匹配条件下,获取一个特定的传输增益,对输出信号的功率没有要求。低噪声:相…

Spring 如何解决循环依赖?Spring三级缓存

什么是循环依赖 说白是一个或多个对象实例之间存在直接或间接的依赖关系&#xff0c;这种依赖关系构成了构成一个环形调用。 自己依赖自己 两个对象间的依赖关系 多个对象间的依赖关系 Spring出现循环依赖的场景 单例的setter注入 Service public class A {Resourceprivate…

五(一)java高级-集合-集合与迭代器(二)

5.1.2 Iterator迭代器 1、Iterator 所谓迭代器&#xff1a;就是用于挨个访问集合元素的工具/对象 方法&#xff1a; boolean hasNext():判断当前遍历集合后面是否还有元素可以迭代Object next():取出当前元素&#xff0c;并往后移→noSuchelementExceptionvoid remove():删…

通过容器化释放云的力量

NCSC (英国国家网络安全中心) 经常被问到的一个问题是是否在云中使用容器。这是一个简单的问题&#xff0c;但答案非常微妙&#xff0c;因为容器化的使用方式有很多种&#xff0c;其中一些方法比其他方法效果更好。 今天&#xff0c;我们发布了有关使用容器化的安全指南&#…

「深度学习」dropout 技术

一、工作原理 1. 正则化网络 dropout 将遍历网络的每一层&#xff0c;并设置消除神经网络中节点的概率。 1. 每个节点保留/消除的概率为0.5: 2. 消除节点&#xff1a; 3. 得到一个规模更小的神经网络&#xff1a; 2. dropout 技术 最常用&#xff1a;反向随机失活 "…

锐捷(二十一)全局地址绑定

vlan划分和vlanif接口配置略&#xff0c;注意vlanif接口里要no shutdown配置如下&#xff1a; Address-bind 192.168.1.1 AAAA.BBBB.CCCCAddress-bind uplink g0/0Address-bind binding-filter loggingAddress-bind install 此时&#xff0c;IP为192.168.1.1 mac地址为AAAA.B…

『运维备忘录』之 Netstat 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是&#xff0c;甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作&#xff0c;持续给大家更新运维工作所需要接触到的知识点&#xff0c;希望大…

GaussDB HCS 轻量化部署软件下载指引

一、Support 账号准备 1. 账号说明 华为的软件服务在华为support网站发布&#xff0c;注册该账号后&#xff0c;可以申请软件、下载离线文档&#xff0c;查看技术案例等功能 2. 账号注册 步骤 1&#xff1a;点击如下官方链接 华为运营商技术支持 - 华为 步骤 2&#xff1…

kafka教程

Kafka 中&#xff0c;Producer采用push模型&#xff0c;而Consumer采用pull模型。 Topic Topic&#xff08;主题&#xff09;是消息的逻辑分类或通道。它是Kafka中用于组织和存储消息的基本单元。一个Topic可以被看作是一个消息发布的地方&#xff0c;生产者将消息发布到一个…

机器学习9-随机森林

随机森林&#xff08;Random Forest&#xff09;是一种集成学习方法&#xff0c;用于改善单一决策树的性能&#xff0c;通过在数据集上构建多个决策树并组合它们的预测结果。它属于一种被称为“集成学习”或“集成学习器”的机器学习范畴。 以下是随机森林的主要特点和原理&…

IT行业含金量高的证书-软考

软考全称计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff0c;软考既是职业资格考试&#xff0c;又是职称资格考试。2021年12月2号发布新版的国家职业资格目录&#xff0c;软考是在计算机技术领域中的唯一的国家职业资格。 一、好处 软考是一个神奇又特…

【数据结构】14 队列(带头结点的链式存储和顺序存储实现)

定义 队列是一个有序线性表&#xff0c;但是队列的插入、删除操作是分别在线性表的两个不同端点进行的。 设一个队列 Q ( a 1 , a 2 , . . . , a n ) Q (a_1, a_2,...,a_n) Q(a1​,a2​,...,an​)&#xff0c;那么 a 1 a_1 a1​被称为队头元素&#xff0c; a n a_n an​为队…

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书信息修改实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…

从互联网的公开信息中,找到属于你的赚钱思路

一、教程描述 人们在互联网上的每一次搜索、每一次关注、每一次点击、每一次点赞、每一次评论、每一次付费&#xff0c;都生成了大量的数据和信息&#xff0c;暴露着人们的真实想法、欲望、恐惧和需求。这些数据和信息&#xff0c;就是我们身边的一座“金矿”&#xff0c;而大…

1【算法】——最大子数组问题(maximum subarray)

一.问题描述 假如我们有一个数组&#xff0c;数组中的元素有正数和负数&#xff0c;如何在数组中找到一段连续的子数组&#xff0c;使得子数组各个元素之和最大。 二.问题分析 分治法求解&#xff1a; 初始状态&#xff1a; low0&#xff1b;highA.length-1&#xff1b;mid&am…