linux中list的基本用法

内核链表

1 list_head 结构

为了使用链表机制,驱动程序需要包含<linux/types.h>头文件,该文件定义了如下结构体实现双向链:

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

2 链表的初始化

2.1 链表宏定义和初始化

可使用以下宏定义并初始化一个链表头部list_head,list_head 不包含数据部分。LIST_HEAD_INIT将链表头的 next 和 prev 指针都指向链表头部,从而形成一个循环结构,和下面介绍的INIT_LIST_HEAD函数一样。

#define LIST_HEAD_INIT(name) { &(name), &(name) }#define LIST_HEAD(name) \struct list_head name = LIST_HEAD_INIT(name)
2.2 链表的初始化

INIT_LIST_HEAD 是一个用于初始化链表头的函数,它将链表头的 next 和 prev 指针都指向自己,从而形成一个循环结构。

static inline void INIT_LIST_HEAD(struct list_head *list)
{WRITE_ONCE(list->next, list);WRITE_ONCE(list->prev, list);
}

如下图所示,链表头的 next 和 prev 指针都指向自己。
在这里插入图片描述

3 list_add

在链表的头部添加新链表项,以下是实现:

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)
{if (!__list_add_valid(new, prev, next))return;next->prev = new;new->next = next;new->prev = prev;WRITE_ONCE(prev->next, new);
}

以下为添加示意图,可以看出后添加节点放在链表的头部,先添加节点靠后,先进后出,后进先出,类似栈结构。
在这里插入图片描述

4 list_add_tail

在链表的尾部添加新链表项,以下是实现:


static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{if (!__list_add_valid(new, prev, next))return;next->prev = new;new->next = next;new->prev = prev;WRITE_ONCE(prev->next, new);
}

以下为添加示意图,可以看出新添加节点放在链表的尾部,后添加节点靠,先进先出,后进后出,类似FIFO结构。
list_add_tail

5 遍历节点

5.1 list_entry

list_entry 宏通过调用 container_of 宏,从链表节点指针获取包含该节点的结构体指针。

/*** list_entry - get the struct for this entry* @ptr: 指向 &struct list_head 的指针。* @type: 包含该节点的结构体类型。* @member: 结构体中的 list_struct 名称。*/
#define list_entry(ptr, type, member) \container_of(ptr, type, member)
5.2 list_for_each

list_for_each 从链表的头部往后依次遍历(next方向)。

/*** list_for_each	-	iterate over a list* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.*/
#define list_for_each(pos, head) \for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)
5.3 list_for_each_entry

通过for循环,依次遍历链表中的每个节点,next方向遍历,每个节点的宿主为pos。

/*** list_for_each_entry	-	iterate over list of given type* @pos:	the type * to use as a loop cursor.* @head:	the head for your list.* @member:	the name of the list_head within the struct.*/
#define list_for_each_entry(pos, head, member)				\for (pos = list_first_entry(head, typeof(*pos), member);	\!list_entry_is_head(pos, head, member);			\pos = list_next_entry(pos, member))

list_first_entry 宏:

#define list_first_entry(ptr, type, member) \container_of((ptr)->next, type, member)

list_first_entry 宏用于获取链表的第一个节点的结构体指针。通过 (ptr)->next 获取到链表头部之后的第一个节点的指针,然后通过 container_of 宏获取包含该节点的整个结构体指针。

list_entry_is_head 宏:

#define list_entry_is_head(pos, head, member) \((pos)->member == (head))

list_entry_is_head 宏用于检查当前节点是否是链表的头部。比较 pos->member 是否等于 head,如果相等,则说明当前节点是链表的头部,即遍历结束。

list_next_entry 宏:

#define list_next_entry(pos, member) \list_entry((pos)->member.next, typeof(*(pos)), member)

list_next_entry 宏用于获取下一个节点的结构体指针。通过 (pos)->member.next 获取到当前节点的下一个节点的指针,然后通过 list_entry 宏获取包含该节点的整个结构体指针。

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

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

相关文章

汽车免拆诊断案例 | 卡罗拉急加速抖动故障排除

车型信息 2017年改款卡罗拉&#xff0c;排量1.2T&#xff0c;行驶里程48800公里。 故障现象 车辆不管在什么状态下&#xff0c;只要是平缓加速&#xff0c;都不会有抖动。车辆静止时&#xff0c;急加速时&#xff0c;也不会有抖动。但是车速达40公里/小时以上&#xff0c;急加…

【python基础】基本数据类型

文章目录 一. Python基本数据类型1. 整数1.1. python的四种进制1.2. 数中的下划线 2. 浮点数3. 复数4. 布尔型5. 运算符5.1. 算术运算符5.2. 比较运算符5.3. 逻辑运算符5.4 运算符优先级 6. 常量 二. 注释三. Python之禅 一. Python基本数据类型 1. 整数 无长度限制&#xff1…

PWM再理解(1)

前言 昨天过于劳累&#xff0c;十点睡觉&#xff0c;本来想梳理一下PWM&#xff0c;今天补上。 PWM内涵 PWM全称&#xff1a;Pulse Width Modulation&#xff0c;也就是脉宽调制的意思&#xff0c;字面意思理解就是对脉冲的宽度进行改变。准确就是通过数字输出对模拟电路进行…

怎样优化 PostgreSQL 中对复杂的日期时间格式转换和时区处理?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 怎样优化 PostgreSQL 中对复杂的日期时间格式转换和时区处理&#xff1f; 怎样优化 PostgreSQL 中对复…

Python | Leetcode Python题解之第257题二叉树的所有路径

题目&#xff1a; 题解&#xff1a; class Solution:def binaryTreePaths(self, root: TreeNode) -> List[str]:paths list()if not root:return pathsnode_queue collections.deque([root])path_queue collections.deque([str(root.val)])while node_queue:node node_…

2024年06月CCF-GESP编程能力等级认证C++编程八级真题解析

本文收录于专栏《C等级认证CCF-GESP真题解析》&#xff0c;专栏总目录&#xff1a;点这里。订阅后可阅读专栏内所有文章。 一、单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 GESP活动期间&#xff0c;举办方从获胜者ABCDE五个人中选出三个人排成一队…

NLP教程:1 词袋模型和TFIDF模型

文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型&#xff1a; 词集模型&#xff1a;单词构成的集合&#xff0c;集合自然每个元素都只有一个&#xff0c;也即词集中的每个单词都只有一个。 词袋模型&#xff1a;在词集的基础上如果一个单词…

上海理工大学24计算机考研考情分析!初复试分值比55:45,复试逆袭人数不算多!

上海理工大学&#xff08;University of Shanghai for Science and Technology&#xff09;&#xff0c;位于上海市&#xff0c;是一所以工学为主&#xff0c;工学、理学、经济学、管理学、文学、法学、艺术学等多学科协调发展的应用研究型大学&#xff1b;是上海市属重点建设大…

Linux系统及常用指令

目录 1、什么是Linux系统 2、为什么要用Linux系统 3、Linux系统的种类 4、如何安装Linux系统 5、常见的适配器种类 6、学习第一个Linux指令 7、安装ssh客户端软件 8、Linux系统的目录结构 9、Linux的常用命令 9.1 目录切换命令 9.2 查看目录下的内容 9.3 查看当前…

vue项目build以后整合到springboot项目里面---------gxl

很多时候我们需要用到vue的组件&#xff0c;但是全栈的背景下懒得去搞前后端分离&#xff0c;很多权限校验后台都写好了&#xff0c;没必要再去做接口或者前端写一遍了&#xff0c;因此我们需要把打包后的项目整合到项目里面。 整合也很简单&#xff0c;照常vue项目开发&#…

UE4-蓝图(可视化编程)学习

一.开关门交互实现 1.需要用到的模板和内容包 2.给门添加碰撞 进入第三人称模板场景&#xff0c;找到门的模型&#xff0c;并将门的模型添加到我们的场景中&#xff1a; 此时我们运行游戏&#xff0c;会发现我们的角色可以穿过我们门的模型&#xff0c;说明我们没有给门添加碰…

水利行业的智慧转型之路:分析智慧水利的核心要素与优势,展望其在提升水资源利用效率、保障水安全方面的广阔前景

目录 引言 一、智慧水利的核心要素 1. 物联网技术 2. 大数据与云计算 3. 人工智能与机器学习 4. 移动互联网与GIS技术 5. 标准化与信息安全 二、智慧水利的优势 1. 提高水资源利用效率 2. 增强水灾害防御能力 3. 提升水环境治理水平 4. 促进水利服务智能化 三、展望…

Grafana :利用Explore方式实现多条件查询

背景 日志统一推送到Grafana上管理。所以&#xff0c;有了在Grafana上进行日志搜索的需求&#xff0c;而进行日志搜索通常需要多条件组合。 解决方案 通过Grafana的Explore的方式实现多条件查询。 直接看操作步骤&#xff1a; 在主页搜索框中输入“Explore” 进入这个界面…

Elasticsearch:评估搜索相关性 - 第 1 部分

作者&#xff1a;来自 Elastic Thanos Papaoikonomou, Thomas Veasey 这是一系列博客文章中的第一篇&#xff0c;讨论如何在更好地理解 BEIR 基准的背景下考虑评估你自己的搜索系统。我们将介绍具体的技巧和技术&#xff0c;以便在更好地理解 BEIR 的背景下改进你的搜索评估流程…

静态网站怎么更新数据

今天看到个问题 我不是行业从业者&#xff0c;但目前遇到一个问题 我公司网站为纯静态&#xff0c;除了直接从html里修改文字外能不能这样 建立一个xml或者txt文档&#xff0c;其中有很多信息&#xff0c;例如网站名称&#xff0c;电话&#xff0c;备案号等&#xff0c;一行一行…

Java 网络编程(TCP编程 和 UDP编程)

1. Java 网络编程&#xff08;TCP编程 和 UDP编程&#xff09; 文章目录 1. Java 网络编程&#xff08;TCP编程 和 UDP编程&#xff09;2. 网络编程的概念3. IP 地址3.1 IP地址相关的&#xff1a;域名与DNS 4. 端口号&#xff08;port&#xff09;5. 通信协议5.1 通信协议相关的…

40.简易频率计(基于等精度测量法)(3)

&#xff08;1&#xff09;BCD8421码&#xff1a;十进制数字转换成BCD8421码的方法 补零&#xff1a;你需要显示多少位数字&#xff0c;就在前面补上四倍的位宽。比如你要显示一个十进制8位的数字&#xff0c;就在前面补上8*432个零。判断&#xff1a;判断补零部分显示的十进制…

叉车指纹一键启动/熄火车辆,“锁”住叉车安全

在现代工业领域&#xff0c;叉车作为重要的物流搬运工具&#xff0c;其安全性和便捷性一直是人们关注的焦点。为此&#xff0c;我们引入了一项技术——叉车指纹一键启动/熄火系统&#xff0c;真正实现了叉车安全的“锁定”。 这项技术不仅仅是简单的启动或关闭车辆的手段&#…

Axure RP移动端医院在线挂号app问诊原型图模板

医疗在线挂号问诊Axure RP原型图医院APP原形模板&#xff0c;是一款原创的医疗类APP&#xff0c;设计尺寸采用iPhone13&#xff08;375*812px&#xff09;&#xff0c;原型图上加入了仿真手机壳&#xff0c;使得预览效果更加逼真。 本套原型图主要功能有医疗常识科普、医院挂号…

云监控(华为) | 实训学习day3(10)

实现数据的增删改查 SpringBoot框架模式 向送外卖一样理解 写程序 1、准备食材(java bean) 2、菜谱(pojo接口->预制->sql 语句) 3、service处理 4、controller 派送 5、用户请求->页面 一、Spring Boot实现增加 第一步&#xff1a;食材(表),用户增加,这里还是用户…