Linux内核常用接口和宏(一)LIST_HEAD
一、LIST_HEAD是什么LIST_HEAD是 Linux 内核中定义并初始化链表头的宏。它用于创建一个双向循环链表的头部节点。c复制下载#include linux/list.h LIST_HEAD(my_list);这个宏展开后等价于c复制下载struct list_head my_list { my_list, my_list };即创建一个名为my_list的链表头它的next和prev指针都指向自己空链表状态。二、内核链表的定义内核链表不是将链表指针嵌入数据中而是将链表节点嵌入数据结构中——这是一种侵入式链表设计。c复制下载// 链表节点结构内核定义 struct list_head { struct list_head *next; struct list_head *prev; }; // 使用时将 list_head 嵌入到你的数据结构中 struct my_data { int id; char name[20]; struct list_head list; // 链表节点 };三、LIST_HEAD的使用方式方式1LIST_HEAD定义链表头c复制下载#include linux/list.h #include linux/slab.h #include linux/module.h // 定义链表头静态初始化 LIST_HEAD(my_list); struct my_data { int id; char name[20]; struct list_head list; }; // 添加节点 void add_node(int id, const char *name) { struct my_data *node; node kmalloc(sizeof(*node), GFP_KERNEL); if (!node) return; node-id id; strncpy(node-name, name, sizeof(node-name) - 1); node-name[sizeof(node-name) - 1] \0; // 插入到链表头部 list_add(node-list, my_list); } // 遍历链表 void print_list(void) { struct my_data *entry; struct list_head *pos; list_for_each(pos, my_list) { entry list_entry(pos, struct my_data, list); printk(KERN_INFO ID: %d, Name: %s\n, entry-id, entry-name); } }方式2LIST_HEAD_INIT动态初始化如果链表头是动态分配的用LIST_HEAD_INIT初始化c复制下载struct list_head *my_list; my_list kmalloc(sizeof(*my_list), GFP_KERNEL); LIST_HEAD_INIT(my_list); // 或者 INIT_LIST_HEAD(my_list)四、内核链表的核心操作函数/宏作用LIST_HEAD(name)定义并初始化链表头INIT_LIST_HEAD(head)初始化已存在的链表头list_add(new, head)在 head 后面插入新节点头插list_add_tail(new, head)在 head 前面插入新节点尾插list_del(entry)从链表中删除节点list_empty(head)判断链表是否为空list_for_each(pos, head)遍历链表pos 是 list_head*list_for_each_safe(pos, n, head)安全遍历支持删除list_entry(ptr, type, member)从 list_head 获取包含它的结构体五、list_entry详解list_entry是内核链表最精妙的部分它通过成员指针反推结构体首地址。c复制下载#define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)-member) *__mptr (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); \ })原理用offsetof计算member在结构体中的偏移量然后用ptr减去这个偏移量得到结构体的首地址。c复制下载struct my_data { int id; char name[20]; struct list_head list; // 假设偏移量是 24 字节 }; // 已知 node-list反推 node 的地址 struct my_data *node list_entry(node-list, struct my_data, list); // 等价于: (struct my_data*)((char*)node-list - 24)六、完整示例内核模块c复制下载#include linux/module.h #include linux/kernel.h #include linux/list.h #include linux/slab.h MODULE_LICENSE(GPL); // 定义链表头 LIST_HEAD(my_list); struct student { int id; char name[20]; struct list_head list; }; // 添加学生 static void add_student(int id, const char *name) { struct student *s kmalloc(sizeof(*s), GFP_KERNEL); if (!s) return; s-id id; snprintf(s-name, sizeof(s-name), %s, name); list_add_tail(s-list, my_list); // 尾插 } // 遍历打印 static void print_students(void) { struct student *s; struct list_head *pos; printk(KERN_INFO Student List \n); list_for_each(pos, my_list) { s list_entry(pos, struct student, list); printk(KERN_INFO ID: %d, Name: %s\n, s-id, s-name); } } // 删除指定 ID 的学生 static void delete_student(int id) { struct student *s; struct list_head *pos, *n; list_for_each_safe(pos, n, my_list) { s list_entry(pos, struct student, list); if (s-id id) { list_del(pos); kfree(s); printk(KERN_INFO Deleted student ID: %d\n, id); return; } } printk(KERN_INFO Student ID %d not found\n, id); } // 清空链表 static void clear_list(void) { struct student *s; struct list_head *pos, *n; list_for_each_safe(pos, n, my_list) { s list_entry(pos, struct student, list); list_del(pos); kfree(s); } } // 模块初始化 static int __init my_init(void) { printk(KERN_INFO Module loaded\n); add_student(1, Alice); add_student(2, Bob); add_student(3, Charlie); print_students(); delete_student(2); print_students(); return 0; } // 模块卸载 static void __exit my_exit(void) { clear_list(); printk(KERN_INFO Module unloaded\n); } module_init(my_init); module_exit(my_exit);七、LIST_HEAD与其他初始化方式对比方式代码适用场景LIST_HEAD(name)LIST_HEAD(my_list);静态定义链表头全局/局部变量INIT_LIST_HEAD(head)INIT_LIST_HEAD(my_list);动态初始化已存在的链表头LIST_HEAD_INIT(name)struct list_head my_list LIST_HEAD_INIT(my_list);定义时初始化与LIST_HEAD等价c复制下载// 三种方式的等价关系 LIST_HEAD(my_list); // 等价于 struct list_head my_list LIST_HEAD_INIT(my_list); // 等价于 struct list_head my_list; INIT_LIST_HEAD(my_list);八、为什么选择侵入式链表特性传统链表非侵入式Linux 侵入式链表节点包含数据节点内包含data指针数据包含list_head类型安全需要void*转换通过list_entry保证类型安全代码复用每个类型需要独立实现一套 API 适用于所有类型内存分配节点和数据分开分配一次分配缓存友好灵活性较低高同一数据可在多个链表中九、常见用法模式模式1结构体包含多个链表节点c复制下载struct task_struct { // ... struct list_head tasks; // 在全局任务链表中 struct list_head ptrace; // 在父进程的跟踪链表中 struct list_head run_list; // 在调度器运行队列中 // ... };模式2遍历并修改c复制下载// 安全遍历允许删除 struct list_head *pos, *n; list_for_each_safe(pos, n, my_list) { struct my_data *entry list_entry(pos, struct my_data, list); if (entry-id target_id) { list_del(pos); kfree(entry); } }十、总结问题答案LIST_HEAD是什么定义并初始化链表头的宏展开后是什么struct list_head name { name, name }链表头的作用作为双向循环链表的入口如何获取包含的结构体list_entry(pos, type, member)遍历用什么list_for_each()或list_for_each_safe()为什么用侵入式通用性强缓存友好一套 API 通吃一句话总结LIST_HEAD是 Linux 内核链表的起点它创建一个空的双向循环链表头配合list_entry和遍历宏构成了内核中最核心、最优雅的数据结构之一

相关新闻

太原无人机行业应用培训

太原无人机行业应用培训

近年来,随着无人机技术在航拍测绘、电力巡检、农业植保、安防救援等领域的广泛应用,具备专业技能的无人机操作人才需求日益旺盛。对于有志于投身这一行业的求职者或从业者来说,选择一家专业、正规的培训机构至关重要。本文将从行业现状、培训…

2026/7/22 16:25:36 阅读更多 →
嵌入式系统启动奥秘:深度解析TI处理器ROM Code架构与调试实战

嵌入式系统启动奥秘:深度解析TI处理器ROM Code架构与调试实战

1. 项目概述与核心价值在嵌入式系统开发中,最神秘也最关键的环节,往往不是我们精心编写的应用代码,而是芯片上电后、我们代码运行前的那“一刹那”。这个瞬间,决定了你的电路板是能亮起第一盏灯,还是永远沉寂。这个幕后…

2026/7/22 16:25:36 阅读更多 →
2026 告别充值!各大网盘怎么免费不限速解析直链下载终极指南

2026 告别充值!各大网盘怎么免费不限速解析直链下载终极指南

在日常数字生活中,网盘是文件传输的重要载体,但“限速”和“网络丢包”经常导致下载进度条卡住。本文将从网络排查、客户端设置、第三方工具辅助及网络环境调优等维度,系统化梳理网盘提速的实用策略。 https://www.pandown.orghttps://www.p…

2026/7/22 16:25:35 阅读更多 →

最新新闻

如何在Windows电脑上轻松运行安卓应用:3种轻量级安卓模拟器方案对比

如何在Windows电脑上轻松运行安卓应用:3种轻量级安卓模拟器方案对比

如何在Windows电脑上轻松运行安卓应用:3种轻量级安卓模拟器方案对比 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾想过在Windows电脑上直接运行安…

2026/7/22 17:12:02 阅读更多 →
Linux基础知识总结3

Linux基础知识总结3

感觉Linux这个知识总结可以写很久 ,文件目录类pwd指令1.基本语法:pwd2.显示当前工作目录的绝对路径pwd /home/user/documentsls指令1.基本语法:ls [选项][目录或是文件]2.常用选项-a:显示当前目录所有的文件和目录,包括…

2026/7/22 17:12:02 阅读更多 →
117、HDR多帧融合算法:曝光序列、运动鬼影消除与合成权重的高效实现

117、HDR多帧融合算法:曝光序列、运动鬼影消除与合成权重的高效实现

117、HDR多帧融合算法:曝光序列、运动鬼影消除与合成权重的高效实现 从一次夜拍翻车说起 去年调试某款旗舰机的主摄HDR,客户反馈夜景模式下拍路灯,灯杆周围总有一圈“鬼影”——不是镜头flare,是算法把不同帧的灯杆边缘叠歪了。我盯着log看了三天,发现是运动检测模块把灯…

2026/7/22 17:12:02 阅读更多 →
Milvus 向量数据库完全指南

Milvus 向量数据库完全指南

1. 深度介绍1.1 Milvus 是什么?Milvus 是一款云原生、开源的向量数据库。在电商场景中,它不仅能通过关键词匹配商品,更能理解用户的“模糊意图”。例如用户搜索“适合夏天穿的透气运动鞋”,传统搜索引擎可能只能匹配包含这些词的商…

2026/7/22 17:12:02 阅读更多 →
Bloc状态管理_Flutter在鸿蒙平台基于流的状态管理方案

Bloc状态管理_Flutter在鸿蒙平台基于流的状态管理方案

作者:付文龙(红目香薰) 仓库地址:https://gitcode.com/feng8403000/FlutterfromBeginnertoAdvancedForHarmonyOS.git 联系邮箱:372699828qq.com 概述 Bloc(Business Logic Component)是一种基…

2026/7/22 17:12:02 阅读更多 →
从PubMed到arXiv,AI搜索精准抓取“被引但未列”的关键文献:科研反脆弱性构建的第4范式(独家算法白皮书节选)

从PubMed到arXiv,AI搜索精准抓取“被引但未列”的关键文献:科研反脆弱性构建的第4范式(独家算法白皮书节选)

更多请点击: https://intelliparadigm.com 第一章:从PubMed到arXiv,AI搜索精准抓取“被引但未列”的关键文献:科研反脆弱性构建的第4范式(独家算法白皮书节选) 传统文献检索常陷入“可见性陷阱”&#xff…

2026/7/22 17:11:02 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统,尤其是像TI C6000系列这样的高性能DSP开发中,我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动,但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案? 在数字化协作环境中,消息通知系统的重要性不言而喻明。但现实情况是,企业级通知方案往往需要复杂的API对接(如企业微信、钉钉、飞书),个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点",乙方听到的是"少做几页"。甲方说"不要太复杂",乙方理解成"别放图表了"。结果交过去,甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里,是…

2026/7/22 0:00:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 12:54:44 阅读更多 →

月新闻