当前位置: 首页 > news >正文

嵌入式链表操作原理详解

嵌入式链表操作原理详解

链表是嵌入式软件开发中最基础的数据结构之一,其设计采用嵌入式链表节点的思想,实现了高度通用的链表管理机制。以下是核心原理和操作的全面解析:


一、基础数据结构
struct list_head {struct list_head *next, *prev;  // 双向指针
};

设计特点

  1. 独立于数据类型的纯链表节点
  2. 通过嵌入到自定义结构体实现数据关联
  3. 双向循环链表结构(头节点的prev指向尾节点)

二、核心操作宏详解
1. 链表初始化
// 静态初始化
LIST_HEAD(my_list);// 动态初始化
struct list_head my_list;
INIT_LIST_HEAD(&my_list);
2. 节点插入
// 头插法(插入到head之后)
list_add(struct list_head *new, struct list_head *head);// 尾插法(插入到head之前)
list_add_tail(struct list_head *new, struct list_head *head);

图示

头插法: head → new → node1 → node2
尾插法: node1 → node2 → new → head
3. 节点删除
// 基础删除
list_del(struct list_head *entry);// 安全删除(删除后初始化节点)
list_del_init(struct list_head *entry);

注意:删除后节点指针被设为LIST_POISON1/2(用于调试)

4. 链表遍历
// 基础遍历
#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)// 安全遍历(允许删除节点)
#define list_for_each_safe(pos, n, head) \for (pos = (head)->next, n = pos->next; pos != (head); \pos = n, n = pos->next)// 反向遍历
list_for_each_prev(pos, head)
5. 获取父结构体 - list_entry
#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)); })

参数解析

  • ptr:链表节点指针(如&data->list
  • type:父结构体类型(如struct my_data
  • member:链表成员名(如list

计算过程

  1. 计算membertype中的偏移量(offsetof
  2. 将节点指针减去偏移量得到父结构体地址
6. 其他关键操作
// 链表判空
list_empty(const struct list_head *head)// 节点移动
list_move(struct list_head *list, struct list_head *head)  // 移动到head后
list_move_tail(struct list_head *list, struct list_head *head) // 移动到head前// 链表合并
list_splice(const struct list_head *list, struct list_head *head) // 合并到head后

三、完整使用示例
// 1. 定义数据结构
struct task_info {pid_t pid;char name[16];struct list_head list;  // 嵌入链表节点
};// 2. 初始化链表头
LIST_HEAD(task_list);// 3. 添加节点
struct task_info *task1 = kmalloc(sizeof(*task1), GFP_KERNEL);
task1->pid = 1001;
strcpy(task1->name, "init");
INIT_LIST_HEAD(&task1->list);
list_add_tail(&task1->list, &task_list);  // 添加到链表尾部// 4. 遍历链表
struct list_head *pos;
struct task_info *task;list_for_each(pos, &task_list) {task = list_entry(pos, struct task_info, list);printk("PID: %d, Name: %s\n", task->pid, task->name);
}// 5. 安全删除所有节点
struct list_head *n;
list_for_each_safe(pos, n, &task_list) {task = list_entry(pos, struct task_info, list);list_del(pos);kfree(task);
}

四、设计优势与原理
  1. 类型无关性

    • 链表操作只处理list_head,与具体数据类型解耦
    • 通过container_of实现类型安全转换
  2. 内存高效

    • 每个节点仅增加8字节(32位)或16字节(64位)开销
    • 无额外内存分配(节点包含在父结构中)
  3. O(1)时间复杂度

    • 插入/删除操作只需修改相邻节点的指针
    // list_add内部实现
    new->next = head->next;
    new->prev = head;
    head->next->prev = new;
    head->next = new;
    
  4. 循环链表设计

    • 头节点的prev指向尾节点,尾节点的next指向头节点
    • 避免遍历时的边界条件检查

五、高级应用技巧
  1. 多链表嵌入

    struct process {struct list_head ready_list;  // 就绪队列struct list_head wait_list;   // 等待队列// ...
    };
    
  2. 哈希链表

    struct hlist_head *htable;  // 哈希表头
    struct hlist_node node;     // 哈希节点
    
  3. RCU安全遍历

    list_for_each_entry_rcu(pos, head, member)
    

六、注意事项
  1. 删除安全

    • 遍历中删除节点必须使用_safe版本
    • 删除后节点指针不可再使用
  2. 内存屏障

    • 多核环境下需使用smp_rmb()/smp_wmb()保证可见性
  3. 对齐要求

    • container_of依赖结构体成员对齐,不可随意填充

这种链表设计被广泛应用于操作系统内核(如进程调度、文件系统、网络协议栈等),其通用性和高效性使其成为系统编程的经典范式。理解其原理对深入操作系统和嵌入式开发至关重要。

http://www.xdnf.cn/news/871867.html

相关文章:

  • 《小明的一站式套餐服务平台:抽象工厂模式》
  • 线夹金具测温在线监测装置:电力设备安全运行的“隐形卫士”
  • GAMES202-高质量实时渲染(Real-Time Physically-based Materials)
  • C++课设:通讯录管理系统(vector、map协作实现)
  • 在VSCode中开发一个uni-app项目
  • 企业级网络安全攻防全景指南:从渗透测试到防御体系建设
  • 基于深度学习(Unet和SwinUnet)的医学图像分割系统设计与实现:超声心脏分割
  • 6. MySQL基本查询
  • Elasticsearch集群状态为RED且存在未分配分片问题排查诊断
  • GitHub 趋势日报 (2025年06月03日)
  • 小白的进阶之路系列之十四----人工智能从初步到精通pytorch综合运用的讲解第七部分
  • Delphi中实现批量插入数据
  • 5分钟了解,Mysql事务事务隔离级别
  • tensorflow image_dataset_from_directory 训练数据集构建
  • 使用 Python 的 psutil 库进行系统资源监控
  • Webpack搭建本地服务器
  • Unity3D 逻辑代码性能优化策略
  • Linux kill 暂停命令
  • 跟着deepseek浅学分布式事务(2) - 两阶段提交(2PC)
  • 人工智能:网络安全的“智能守护者”
  • 录制mp4
  • Kali Linux 安全工具解析
  • Ros(控制机器人运动)
  • .NET 原生驾驭 AI 新基建实战系列(四):Qdrant ── 实时高效的向量搜索利器
  • JVMTI 在安卓逆向工程中的应用
  • 【Oracle】存储过程
  • 纹理压缩格式优化
  • OpenCV 自带颜色表实现各种滤镜
  • 【Netty源码分析总结】
  • 使用 Unstructured 开源库快速入门指南