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.xdnf.cn/news/1483592.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MongoDB教程(十二):MongoDB数据库索引

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…

Vue封装文件上传组件(支持图片、PDF、Excel、word预览下载)

一、准备工作 安装预览依赖包&#xff1a;exceljs、mammoth、vue-pdf 二、封装组件 文件上传组件 fileUploadPro.vue。默认预览、下载是true,可通过isPreView、isDownLoad控制 <template><div style"display: flex"><el-uploadmultipleaction&qu…

SSM 整合(Spring + MyBatis;Spring + Spring MVC)

1. SSM 整合(Spring MyBatis&#xff1b;Spring Spring MVC) 文章目录 1. SSM 整合(Spring MyBatis&#xff1b;Spring Spring MVC)2. 引入相关依赖3. SSM 整合3.1 创建包结构 4. Spring 整合 MyBatis4.1 编写 jdbc.properties4.2 编写 DataSourceConfig 数据源配置4.3 编…

大数减法c++

这里写目录标题 key key 检查减数和被减数的大小&#xff0c;大的放前&#xff0c;小的放后确定结果是正数&#xff0c;还是负数&#xff0c;即符号位从低位开始减如果a[i]<b[i]&#xff0c;则向高位借1当10&#xff0c;a[i1]–;a[i]10 #include <iostream> #include…

[MySQL][索引][下][理解索引]详细讲解

目录 0.前期准备1.为何IO交互要是Page&#xff1f;2.理解单个Page3.理解多个Page4.页目录5.单页情况6.多页情况7.总结复盘8.InnoDB 在建立索引结构来管理数据的时候&#xff0c;其他数据结构为何不行&#xff1f;9.聚簇索引 vs 非聚簇索引 0.前期准备 建立测试表 create table …

云手机结合自主ADB命令接口 提升海外营销效率

现在&#xff0c;跨境电商直播已经成为在线零售的重要渠道&#xff0c;在大环境下&#xff0c;确保直播应用的稳定性和用户体验至关重要。 云手机支持自主ADB命令接口&#xff0c;为电商直播营销提供了技术支持&#xff0c;使得应用开发、测试、优化和运维更加高效。 什么是A…

Linux-交换空间(Swap)管理

引入概念 在计算机中&#xff0c;硬盘的容量一般比内存大&#xff0c;内存&#xff08;4GB 8GB 16GB 32GB 64GB…&#xff09;&#xff0c;硬盘&#xff08;512GB 1T 2T…&#xff09;。 冯诺依曼的现代计算机结构体系里面的存储器就是内存 内存是一种易失性存储器&#xff0c…

0718,TCP协议,三次握手,四次挥手

爬东西只能明天了喵 上课喵&#xff1a; TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;的状态迁移图 这图别看&#xff0c;会瞎 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;的状态迁移图描述…

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

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

注册安全分析报告:东方航空

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

ruoyi部署前端,服务器访问模块报错:Error: Cannot find module ‘@/views/system/user/index’

找到permission.js文件 loadView修改代码如下&#xff1a; export const loadView (view) > {if (process.env.NODE_ENV development) {return (resolve) > require([/views/${view}], resolve)} else {// 使用 import 实现生产环境的路由懒加载// return () > imp…

Linux下vim编辑器的使用方法

Vim编辑器 vim kk 使用vim来创建或编辑 kk文件 一般模式下的操作 x 为向后删除一个字符 nx 连续向后删除n个字符 dd 删除光标所在行 ndd 删除光标所在的向下n行 yy 复制光标所在的那一行 nyy 复制光标所在的向下n列 p 将已复制的数据在光标下一行粘贴上 P 则为贴在光标的上一…

【golang-ent】go-zero框架 整合 ent orm框架 | 解决left join未关联报错的问题

一、场景 1、子表&#xff1a;cp_member_point_history cp_member_point_history表中字段&#xff1a;cp_point_reward_id 是cp_point_reward的主键id 当本表中的cp_point_reward_id字段为0&#xff08;即&#xff1a;没有可关联主表的&#xff09; CREATE TABLE cp_member_poi…

studio编译报错java.lang.NullPointerException

安卓studio编译报错&#xff0c;这个是一个新建的项目就报错&#xff0c;原因是 implementation androidx.appcompat:appcompat:1.7.0版本太高&#xff0c;修改后版本 implementation androidx.appcompat:appcompat:1.4.0&#xff0c; 编译又报错 18 issues were found wh…

浅聊 Three.js 屏幕空间反射SSR-SSRShader

浅聊 Three.js 屏幕空间反射SSR(2)-SSRShader 前置基础 渲染管线中的相机和屏幕示意图 -Z (相机朝向的方向)||| -------------- <- 屏幕/投影平面| | || | || | (f) | <- 焦距| | ||…

SpringBoot框架学习笔记(三):Lombok 和 Spring Initailizr

1 Lombok 1.1 Lombok 介绍 &#xff08;1&#xff09;Lombok 作用 简化JavaBean开发&#xff0c;可以使用Lombok的注解让代码更加简洁Java项目中&#xff0c;很多没有技术含量又必须存在的代码&#xff1a;POJO的getter/setter/toString&#xff1b;异常处理&#xff1b;I/O…

解决gitlab报502的问题

external_url http://10.7.24.6:10002 puma[port] 8091 sudo gitlab-ctl reconfigure sudo gitlab-ctl restart 设置管理员密码&#xff1a; 1. 切换目录&#xff1a;cd 安装目录gitlab的bin目录下 2. 以root执行 &#xff1a;gitlab-rails console命令&#xff0c;等待…

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

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

PyTorch 深度学习实践-处理多维特征的输入

视频指路 参考博客笔记 参考笔记二 通过多个线性模型来模拟非线性的空间变换&#xff0c;矩阵计算就是不同维度之间的空间转换 说明&#xff1a;1、乘的权重(w)都一样&#xff0c;加的偏置(b)也一样。b变成矩阵时使用广播机制。神经网络的参数w和b是网络需要学习的&#xff0c…

0718vscode问答

终于来到 qt # Question 多态 # Answer 多态是面向对象编程中的一个重要概念&#xff0c;指的是同一个接口可以有多种不同的实现方式。多态性允许我们使用一个统一的接口来处理不同类型的对象&#xff0c;从而提高代码的灵活性和可扩展性。 在Java中&#xff0c;多态可以通过以…