博客
关于我
Kernel
阅读量:654 次
发布时间:2019-03-15

本文共 1786 字,大约阅读时间需要 5 分钟。

kernel 中链表的结构与使用

在 Linux 内核中,链表是一种双向循环链表,广泛用于数据结构的组织和操作。以下将详细介绍 chain 表的结构及其使用方法。


链表的结构

在内核中,链表的结构体定义为:

struct list_head {    struct list_head *next, *prev;};

每个链表成员都包含两个指针:nextprev。这两个指针分别指向链表的下一个和前一个成员。当链表中只有一个头节点时:

  • 头节点的 next 公式指针指向自己。
  • 头节点的 prev 公式指针也指向自己。

当添加第二个成员时:

  • 新成员的 next 指针指向原链表的头节点。
  • 原链表头节点的 next 公式指向新成员。
  • 原链表头节点的 prev 公式指向新成员。

例如:

head -> node1 -> node2 -> head

此外,内核链表是双向循环的,即最后一个节点的 next 指针指向链表的头节点。


链表的使用

链表在内核中的使用通常与数据结构体配合使用。具体步骤如下:

  • 定义链表结构体:在链表节点外定义一个包含链表结构体的数据结构。

    struct app_info {    int app_id;    int up_flow;    int down_flow;    struct list_head app_info_node;};
  • 初始化链表:使用 INIT_LIST_HEAD 宏初始化链表头节点。

    struct list_head *head = &app_info_list->app_info_node;INIT_LIST_HEAD(head);
  • 插入新节点:使用 list_add_taillist_add 函数分别在链表头或尾部插入新节点。

    list_add_tail(&app1->app_info_node, head);
  • 获取节点结构体:使用 list_entry 宏从链表节点获取对应的数据结构体。

    temp_app = list_entry(&app3->app_info_node, app_info, app_info_node);

  • container_oflist_entry 的使用

    container_oflist_entry 宏用于将链表节点转换为相应的数据结构体,前者用于获取 (container_of) 链表节点的父结构体,后者用于获取完整的结构体信息。

    这两个宏的实现原理如下:

    宏定义

    #define-offs (type, member)container_of(ptr, type, member) {    const typeof( (type*)0-> member ) * __mptr = (ptr);    (type *) ( (char *) __mptr - offsetof(type, member) );}list_entry(ptr, type, member) {    return container_of(ptr, type, member);}

    它们的作用

  • container_of:获取一个链表节点的父结构体。

    • 它通过 ptr 获取链表节点 member 的地址。
    • 强制转换 member 的类型并赋值给 __mptr
    • 计算出父结构体的地址并返回。
  • list_entry:获取含有链表节点的完整数据结构体。


  • 链表的实际应用

    在内核中,链表广泛应用于以下场景:

    • 设备注册:用于创建和管理设备的注册表。
    • 任务队列:实现任务的执行顺序控制。
    • 内核模块:组织内核模块之间的依赖关系。

    每个链表成员都可以携带任意类型的数据,只要结构体定义明确即可。


    链表的优化与扩展

    在实际使用中,可以通过以下方式优化链表性能:

  • 分而不和:将链表分割为双向链表和循环队列,根据需求选择适合的结构。
  • 使用电梯停车法:减少.realmlock的争用。
  • 链表倍向:支持多指针访问(通常用于优化缓存)。
  • 此外,可以结合 container_oflist_entry 等宏,实现链表操作的快速迭代和修改。


    通过理解和实践 chain 表的结构及使用方法,可以更好地掌握 Linux 内核开发的核心技巧。这些建议和实例可以帮助开发者更高效地编写和优化代码。

    转载地址:http://gewmz.baihongyu.com/

    你可能感兴趣的文章
    Ploly Dash,更新一个Dash应用程序JJJA上的实时人物
    查看>>
    Ploly烛台的定制颜色
    查看>>
    Ploly:如何在Excel中嵌入完全交互的Ploly图形?
    查看>>
    plotloss记录
    查看>>
    Plotly (Python) 子图:填充构面和共享图例
    查看>>
    Plotly 中的行悬停文本
    查看>>
    Plotly 停用 x 轴排序
    查看>>
    Plotly 域变量解释(多图)
    查看>>
    Plotly 绘制表面 3D 未显示
    查看>>
    Plotly-Dash 存在未知问题并创建“加载依赖项时出错“;通过使用 Python-pandas.date_range
    查看>>
    Plotly-Dash:如何过滤具有多个数据框列的仪表板?
    查看>>
    Plotly:如何为 x 轴上的时间序列设置主要刻度线/网格线的值?
    查看>>
    Plotly:如何从 x 轴删除空日期?
    查看>>
    Plotly:如何从单条迹线制作堆积条形图?
    查看>>
    Plotly:如何以 Root 样式绘制直方图,仅显示直方图的轮廓?
    查看>>
    Plotly:如何使用 Plotly Express 组合散点图和线图?
    查看>>
    Plotly:如何使用 plotly.graph_objects 和 plotly.express 定义图形中的颜色?
    查看>>
    Plotly:如何使用 Python 对绘图对象条形图进行颜色编码?
    查看>>
    Plotly:如何使用 updatemenus 更新一个特定的跟踪?
    查看>>
    Plotly:如何使用长格式或宽格式的 pandas 数据框制作线图?
    查看>>