数据结构(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个流行的开源数据治理工具
数字化时代,数据是已经成为最宝贵的资产之一。数据支撑着我们的政府、企业以及各类组织的所有流程,并为决策以及智能化服务提供支撑。大数据有大用途,但是也可能隐藏着巨大的风险,特别是如果我们对数据的情况不是很了解的时候&…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
