首页 > 其他分享 >内核链表基本知识

内核链表基本知识

时间:2024-09-05 19:54:13浏览次数:9  
标签:klink 基本知识 结点 链表 pnode phead 内核 NULL

一、基本知识

内核链表:可以给里面的每一个数据都可以存储不同的数据的类型,结构体成员里面(将结点放在数据中)

1、实质

内核链表:有头的、双向循环链表

2、注意

  • 结构体第一个成员即为结构体的首地址
  • 该链表里面的数据主要由两部分构成 前驱结点,后继结点,该节点作为数据放在数据中

3、怎么通过链表找到对应的数据结点

  • 内存链表提供了,offsetof (获得的是结构体成员到结构体开头的偏移量)contianer_of(两个宏)(通过偏移量获取结构体首地址)
  • 结构体指针-偏移量就获得了位置

4、循环链表

第一个指针的前驱结点指向最后一个结点,最后一个结点的尾指针指向第一个结点

二、内联链表的特点

1、可扩展性

内核代码都没有写成死代码,对于后续的要求可以进行灵活改变、方便修改和追加

2、封装性

函数的接口的封装性比较好,属于程序与程序之间的高内聚低耦合的特点。

3、数据类型多变

在这里是将结点作为数据插入,故可以灵活的拓展数据的数据结构,也就是说常用的带数据域的链表降低了链表的通用性,不容易扩展。linux内核定义的链表结构不带数据域,只需要两个指针完成链表的操作。将链表节点加入数据结构,具备非常高的扩展性,通用性。

4、遍历效率高

因为一个结点都包含着前一个结点,也就是说从任一一个结点都可以进行遍历,遍历的效率比较高。

三、链表的操作

3.1、创建结点

Klink_t *create_link()
{
    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;
}

3.2、头插

int push_klink_head(Klink_t *klink,void *p)
{
    KNode_t *knode = (KNode_t *)p;
    knode->ppre = NULL;
    knode->pnext = NULL;
    knode->pnext = klink->phead;
    if(klink->phead != NULL)
    {//可能没有前驱结点
        klink->phead->ppre = knode;
    }
    klink->phead = knode;
    klink->clen++;
    return 0;
}

3.3、尾插

int push_klink_tail(Klink_t *klink,void *p)
{
    KNode_t *knode = (KNode_t *)p;
    knode->ppre = NULL;
    knode->pnext = NULL;
    KNode_t *q = klink->phead;
    if(klink->phead == NULL)
    {
        push_klink_head(klink,knode);
    }
    while(q->pnext != NULL)
    {
        q = q->pnext;
    }
    q->pnext = knode;
    knode->ppre = q;  
    klink->clen++;
   

3.4、遍历

void klink_for_each(Klink_t *klink,void (*func)(void *))
{
    KNode_t *pnode = klink->phead;
    while(pnode != NULL)
    {
        func(pnode);
        pnode = pnode->pnext;
    }
    printf("\n");
}

3.5、查找

KNode_t *find_link(Klink_t *klink,void *t,CMP_t func)
{
    KNode_t *pnode = klink->phead;
    while(pnode != NULL)
    {
        if(func(t,pnode))
        {
            return pnode;
        }
        pnode = pnode->pnext;
    }
    return NULL;
}

3.6、头删

int pop_klink_head(Klink_t *klink)
{ 
    if(klink->phead == NULL)
    {
        return 0;
    }
    KNode_t *pnode = klink->phead;
    klink->phead = pnode->pnext;
    if(klink->phead != NULL)
    {
        klink->phead->ppre = NULL;
    }
    free(pnode);
    klink->clen--;
    return 1;
}

3.7、销毁

int pop_klink_head(Klink_t *klink)
{ 
    if(klink->phead == NULL)
    {
        return 0;
    }
    KNode_t *pnode = klink->phead;
    klink->phead = pnode->pnext;
    if(klink->phead != NULL)
    {
        klink->phead->ppre = NULL;
    }
    free(pnode);
    klink->clen--;
    return 1;
}

标签:klink,基本知识,结点,链表,pnode,phead,内核,NULL
From: https://blog.csdn.net/weixin_63722559/article/details/141927994

相关文章

  • 力扣86.分割链表
    classSolution{publicListNodepartition(ListNodehead,intx){//初始化两个链表的头节点和尾节点,分别用于存储小于x和大于等于x的节点ListNodeleftHead=null,leftTail=null;ListNoderightHead=null,rightTail=null;//临时变量,用于遍历原链......
  • arm内核(core),arm微内核(microarchitecture),arm结构(architecture),arm指令集(instruct
    References:初识ARM(内核、SoC)一文彻底分清ARM架构、内核、指令集等相关概念【ARM】(1)架构简介什么是ARM、Cortex、SOC、arm架构、ARMv7、ARM指令集?超详细!!!!Learnthearchitecture-IntroducingtheArmarchitecture微架構-wikipediaInstructionsetarchitectureMicro......
  • 怎么理解cpu内核&多核
    References:cpu多核的来历,cpu性能与核心数的联系如何理解处理器、CPU、多处理器、内核、多核?内核/逻辑处理器/线程/多线程/多CPU/多核CPUCPU相关概念:物理cpu数、核数、逻辑cpu数,12核20线程实例分析Multi-CoreonChipArchitecture*doc-IKsingle-corevsmulti-core......
  • centos7 内核升级
    需要下载三个rpm包wgethttp://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-devel-4.4.215-1.el7.elrepo.x86_64.rpmwgethttp://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-headers-4.4.215-1.el7.elrepo.......
  • Linux 内核 6.11 RC6 发布!
    2024年9月2日,Linux内核开发者LinusTorvalds宣布了Linux内核6.11的第六个候选版本(RC6)的发布。与以往的发布时间相比,由于Torvalds正在国外旅行,这次的RC6提前半天发布。这是6.11版本开发周期的又一部分,主要是继续修复和稳定系统的各个组成部分,特别是文件系统、......
  • Linux 系统中的 `/etc/sysctl.conf` 配置文件内核参数设置
    以下是对这些参数的详细解释:网络参数net.ipv4.ip_forward=0:禁用IP转发,防止系统作为路由器转发数据包。net.ipv4.conf.default.rp_filter=1:启用反向路径过滤,增加网络安全性,防止IP地址欺骗。net.ipv4.conf.default.accept_source_route=0:禁用源路由选项,防止数据包通......
  • Java-数据结构-链表-习题(三)(๑´ㅂ`๑)
    文本目录:​❄️一、习题一:  ▶ 思路: ▶ 代码:​❄️二、习题二: ▶ 思路: ▶ 代码:​❄️三、习题三: ▶ 思路: ▶ 代码:​❄️四、习题四:    ▶ 思路:   ▶ 代码:​❄️五、习题五: ▶ 思路:    ▶ 代码:  ​❄️六、习题六:   ......
  • Java顺序表和链表万字详解
    1.线性表的概念线性表(linearlist)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,......
  • 面向对象程序设计之链表 list 的简析(C++)
    简介:链表是一个双向的结构,与string与vector不同的是他不支持[]访问,因为链表是由一个节点一个节点连接而成的,并不连续。我们可以在常数量级内对于链表进行插入与删除数据1.构造函数我们在cplusplus.com中可以查到链表总共有四种构造的方式:1.无参构造(默认构造);2.使用n个va......
  • Linux内核如何通过内存回收和压缩机制来管理物理内存
    大家好,今天给大家介绍Linux内核如何通过内存回收和压缩机制来管理物理内存,文章末尾附有分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!可进群免费领取。Linux内核通过一系列复杂的内存回收和压缩机制来有效管理物理内存,确保系统能够在不同负载......