数据结构(3)内核链表
一、内核链表
内核链表是一种在操作系统内核中使用的数据结构,主要用于管理和组织内核对象。它是有头双向链表的一种实现。
内核链表的特点
-
双向链表: 内核链表的每个节点都包含指向前一个节点和后一个节点的指针,这使得在链表中进行插入和删除操作时更加高效。
-
高效性: 内核链表的操作通常在内核空间中进行,避免了用户空间和内核空间之间的上下文切换,从而提高了性能。
-
简化的接口: 内核链表通常提供了一组宏和函数来简化链表的操作,例如添加、删除和遍历节点。这些操作通常是以宏的形式实现,以减少函数调用的开销。
1. offsetof
offsetof 是一个宏,用于获取结构体中某个成员相对于结构体起始位置的字节偏移量。它的定义通常如下:
#define offsetof(type, member) ((size_t) &((type *)0)->member)
用法
-
参数:
type: 结构体的类型。member: 结构体中的成员名。
-
返回值: 返回指定成员相对于结构体起始位置的字节偏移量。
2. container_of
container_of 是一个宏,用于根据结构体成员的指针获取包含该成员的结构体的指针。它的定义通常如下:
#define container_of(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member)))
用法
-
参数:
ptr: 指向结构体成员的指针。type: 结构体的类型。member: 结构体中的成员名。
-
返回值: 返回指向包含该成员的结构体的指针。
二、内核链表的实现
KNode_t:代表链表中的一个节点。
包含两个指针:
ppre: 指向前一个节点的指针。
pnext: 指向下一个节点的指针。
typedef struct knode
{ struct knode *ppre; struct knode *pnext;
} KNode_t;
KLink_t:代表整个链表。
包含以下成员:
phead: 指向链表头节点的指针。
clen: 当前链表中的节点数量。
mutex: 用于线程安全的互斥锁,确保在多线程环境中对链表的操作是安全的。
typedef struct klink
{ KNode_t *phead; int clen; pthread_mutex_t mutex;
} KLink_t;
1. create_klink
KLink_t *create_klink()
{ KLink_t *pklink = malloc(sizeof(KLink_t)); if (NULL == pklink) { perror("fail malloc"); return NULL; } pklink->phead = NULL; pklink->clen = 0; pthread_mutex_init(&(pklink->mutex), NULL); return pklink;
}
功能: 创建一个新的链表。
步骤:
使用 malloc 分配内存。
检查内存分配是否成功。
初始化链表头指针为 NULL,节点计数为 0,并初始化互斥锁。
返回值: 返回指向新链表的指针。
2. push_klink_head
int push_klink_head(KLink_t *pklink, void *p)
{ KNode_t *pnode = (KNode_t *)p; pnode->pnext = NULL; pnode->ppre = NULL; pnode->pnext = pklink->phead; if (pklink->phead != NULL) { pklink->phead->ppre = pnode; } pklink->phead = pnode; pklink->clen++; return 0;
}
功能: 将一个节点插入到链表的头部。
步骤:
将传入的节点指针 p 转换为 KNode_t 类型。
设置新节点的前后指针。
将新节点插入到链表头部,并更新头指针。
增加链表的节点计数。
返回值: 返回 0 表示成功。
3. klink_for_each
void klink_for_each(KLink_t *pklink, void (*pfun)(void *))
{ KNode_t *pnode = pklink->phead; while (pnode != NULL) { pfun(pnode); pnode = pnode->pnext; } printf("\n");
}
功能: 遍历链表并对每个节点执行指定的函数。
参数:
pklink: 指向链表的指针。
pfun: 指向处理每个节点的函数的指针。
步骤:
从链表头开始遍历,调用传入的函数处理每个节点。
4. push_klink_tail
int push_klink_tail(KLink_t *pklink, void *q)
{ KNode_t* pnode = (KNode_t*)q; pnode->pnext = NULL; pnode->ppre = NULL; if (NULL == pklink->phead) { pklink->phead = pnode; } KNode_t* p = pklink->phead; while (p->pnext) { p = p->pnext; } p->pnext = pnode; pnode->ppre = p; return 0;
}
功能: 将一个节点插入到链表的尾部。
步骤:
将传入的节点指针 q 转换为 KNode_t 类型。
设置新节点的前后指针。
如果链表为空,将新节点设置为头节点。
否则,遍历到链表的最后一个节点,并将新节点添加到尾部。
返回值: 返回 0 表示成功。
5. pop_klink_head
int pop_klink_head(KLink_t *pklink)
{ if (NULL == pklink->phead) { return 0; } KNode_t* pnode = pklink->phead; pklink->phead = pnode->pnext; if (pklink->phead != NULL) { pklink->phead->ppre = NULL; } free(pnode); return 0;
}
功能: 从链表的头部删除一个节点。
步骤:
检查链表是否为空。
保存当前头节点,并将头指针更新为下一个节点。
如果新的头节点不为空,更新其前指针。
释放被删除节点的内存。
返回值: 返回 0 表示成功。
三、内核链表和普通双向链表的区别
1. 目的和使用场景
-
内核链表:
- 主要用于操作系统内核中,处理任务调度、资源管理、设备驱动等。
- 需要高效的插入、删除和遍历操作,以满足实时性和性能要求。
-
普通双向链表:
- 通常用于应用程序中,处理数据存储、缓存、队列等。
- 设计上更关注易用性和灵活性,而不是极端的性能优化。
2. 结构和实现
-
内核链表:
- 通常使用更简洁的结构,可能不包含数据部分,节点结构只包含指向前后节点的指针。
- 数据部分通常与链表分开,链表节点只负责链接,数据通过其他方式管理。
-
普通双向链表:
- 节点结构通常包含数据部分和指向前后节点的指针。
- 每个节点都是完整的,包含数据和指针,便于直接操作。
3. 线程安全
-
内核链表:
- 设计时通常考虑到多线程环境,可能会使用互斥锁或其他同步机制来确保线程安全。
- 需要处理并发访问,确保数据一致性。
-
普通双向链表:
- 通常不考虑线程安全,使用时需要开发者自行管理。
- 在单线程环境中使用时,简单易用,但在多线程环境中可能会出现数据竞争问题。
相关文章:
数据结构(3)内核链表
一、内核链表 内核链表是一种在操作系统内核中使用的数据结构,主要用于管理和组织内核对象。它是有头双向链表的一种实现。 内核链表的特点 双向链表: 内核链表的每个节点都包含指向前一个节点和后一个节点的指针,这使得在链表中进行插入和删除操作时更…...
Linux 硬件学习 s3c2440 arm920t蜂鸣器
1.查找手册时钟图,输入12m想要通过pll得到400m的信号 2.对比pll值,找到最近的为405,得到pll中mdiv为127,pdiv为2,sdiv为1 3.想要得到fclk400,hclk100,pclk50,对比分频比例࿰…...
提交保存,要做重复请求拦截,避免出现重复保存的问题
**问题:**前端ajax提交数据的时候,当频繁点击的时候,或者两个账号以相同数据创建的时候,会出现问题。 **处理办法:**前端拦截,防止重复提交数据,在上一次请求返回结果之后才允许提交第二次&…...
华为 HCIP-Datacom H12-821 题库 (3)
有需要题库的可以看主页置顶 1.运行 OSPF 协议的路由器在交互 DD 报文时,会使用以下哪一个参数选举主从关系? A、接口的 IP 地址 B、接口的 DR 优先级 C、Area ID D、Router ID 答案:D 解析: Router-ID 大的为主&a…...
spring-boot 事件
事件触发时机常用监听器描述ApplicationStartingEvent应用启动时LoggingApplicationListener:决定加载哪个日志系统ApplicationEnvironmentPreparedEvent创建Environment之后BootstrapApplicationListener:加载spring-cloud bootstrap配置文件࿱…...
合碳智能 × Milvus:探索化学合成新境界——逆合成路线设计
合碳智能(C12.ai)成立于2022年,致力于运用AI和具身智能技术,为药物研发实验室提供新一代智能化解决方案,推动实验室从自动化迈向智能化,突破传统实验模式与人员的依赖,解决效率和成本的瓶颈&…...
二分查找 | 二分模板 | 二分题目解析
1.二分查找 二分查找的一个前提就是要保证数组是有序的(不准确)!利用二段性! 1.朴素二分模板 朴素二分法的查找中间的值和目标值比较 while(left < right) // 注意是要: < {int mid left (right -left) / 2;…...
uni-app应用更新(Android端)
关于app更新,uni-app官方推荐的是 uni-upgrade-center,看了下比较繁琐,因此这里自己实现检查更新并下载安装的逻辑。 1.界面效果 界面中的弹框和 进度条采用了uView 提供的组件 2.检查更新并下载安装 一、版本信息配置在服务端,…...
JavaEE(2):前后端项目之间的交互
现在,在网页中通过超链接,表单就可以向后端发送请求,后端也可以正常响应内容。 以前通过表单访问后端的请求方式称为同步请求 同步请求 当网页与后端交互时,前端不能再进行其他操作 服务器端响应回来的内容,会把整个浏…...
(已开源-CVPR 2024)YOLO-World: Real-Time Open-Vocabulary Object Detection
169期《YOLO-World Real-Time Open-Vocabulary Object Detection》 You Only Look Once (YOLO) 系列检测模型是目前最常用的检测模型之一。然而,它们通常是在预先定义好的目标类别上进行训练,很大程度上限制了它们在开放场景中的可用性。为了解决这一限制…...
Spring6梳理4——SpringIoC容器
以上笔记来源: 尚硅谷Spring零基础入门到进阶,一套搞定spring6全套视频教程(源码级讲解)https://www.bilibili.com/video/BV1kR4y1b7Qc 目录 4.1 前言 4.2 IoC容器 4.2.1 控制反转(IoC) 4.2.2 依赖注入 4.2.3 IoC容器在Spri…...
SpringBoot2:请求处理原理分析-FORM表单请求接口
一、RESTFUL简介 Rest风格支持(使用HTTP请求方式,动词来表示对资源的操作) 以前:/getUser 获取用户 /deleteUser 删除用户 /editUser 修改用户 /saveUser 保存用户 现在: /user GET-获取用户 DELETE-删除用户 PUT-修改…...
Monkey日志ANR、CRASH、空指针异常及其他异常数据分析
引言 在Android开发过程中,monkey测试是一种常用的随机测试手段,用于模拟用户的各种操作来发现应用中的稳定性问题。通过monkey测试生成的日志文件包含了丰富的信息,包括应用程序崩溃(Crash)、无响应(ANR&…...
Vue 3结合Element Plus中,实现一个级联选择器(Cascader)来展示省市区
在Vue 3结合Element Plus中,实现一个级联选择器(Cascader)来展示省市区(甚至到更细分的级别,如街道、小区等)的联动选择是一个常见的需求。Element Plus的Cascader组件非常适合这样的场景,因为它…...
使用卫星仿真软件STK的一些应用和思考(星地链路、星间链路)
目录 任务描述利用STK建模星地协同系统3个GEO高轨卫星240/20/1 Walker-Star Constellation 低轨卫星星座地面站或者地面设备 链路建模与数据提取处理星地链路星间链路数据读取的几种方法最麻烦的方法使用Matlab与STK互联接口使用大规模使用Chain 总结 任务描述 在一个星地协同…...
pytorch对不同的可调参数,分配不同的学习率
在 PyTorch 中,你可以通过为优化器传递不同的学习率来针对不同的可调参数分配不同的学习率。这通常通过向优化器传递一个字典列表来实现,其中每个字典指定特定参数组的学习率。下面是一个示例代码,展示了如何实现这一点: import …...
零基础学习Python(八)—— time模块、request模块、数据分析和自动化办公相关模块、jieba模块、文件操作和os相关模块的简单介绍
1. time模块 time():获取当前时间戳,是一个数字 localtime():返回一个time.struct_time对象,里面有年月日时分秒,还有星期几(0表示星期一)和今年的第几天 import timeprint(time.time()) pri…...
快速回顾-HTML5
HTML5-常用的标签:https://blog.csdn.net/TKOP_/article/details/111395865 <!-- HTML5:声明文档类型的标签 --> <!DOCTYPE html><!-- 用于声明网页的主要语言为简体中文 --> <!-- 帮助搜索引擎、浏览器等理解网页的语言内容,以便…...
视频技术未来展望:EasyCVR如何引领汇聚融合平台新趋势
随着科技的飞速发展,视频技术已成为现代社会不可或缺的一部分,广泛应用于安防监控、娱乐传播、在线教育、电商直播等多个领域。本文将探讨视频技术的未来发展趋势,并深入分析TSINGSEE青犀EasyCVR视频汇聚融合平台的技术优势,展现其…...
7个流行的开源数据治理工具
数字化时代,数据是已经成为最宝贵的资产之一。数据支撑着我们的政府、企业以及各类组织的所有流程,并为决策以及智能化服务提供支撑。大数据有大用途,但是也可能隐藏着巨大的风险,特别是如果我们对数据的情况不是很了解的时候&…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
