欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 内核链表及使用

内核链表及使用

2024/10/25 7:32:37 来源:https://blog.csdn.net/2301_80338792/article/details/141941266  浏览:    关键词:内核链表及使用

内核链表是操作系统内核中用于管理内存中数据结构的一种方式,特别是在Linux内核中。它提

拱了一种灵活且高效的方法来组织和管理数据,如进程、缓冲区、定时器等。内核链表的设计允许

快速插入、删除和遍历节点,这对于需要高效率和实时响应的内核操作至关重要。

内核链表:

可以给里面放不止一套相同类型的数据,但数据的对象不同

内核链表:

双向链表、有头链表,循环链表

内核链表的特点:

  1. 双向链表:大多数内核链表是双向循环链表,这意味着每个节点都有指向前一个和后一个节点的指针。这使得从链表中任意位置插入和删除节点都变得容易。

  2. 内存管理:内核链表通常用于管理内核空间的内存,因此它们需要高效且占用空间小。

  3. 并发控制:由于内核代码可能被多个处理器或线程同时访问,内核链表的实现通常需要考虑并发控制,如使用自旋锁或互斥锁。

  4. 性能优化:内核链表的设计通常针对性能进行了优化,以减少内存访问延迟和提高处理速度。

将节点放在存储数据的结构体中

怎么通过节点获取数据呢------->内核提供了两个宏:

offset of:获取结构体成员到结构体开头的偏移量

contianer_of:通过偏移量获取结构体首地址

构建一个类内核链表实现航班及乘客查询(即将节点放在结构体中)

航班部分:

struct passager * create_passager(char *name,int flt_num,int sit_num,char card)
{struct passager *p = malloc(sizeof(struct passager));if(NULL == p){return NULL;}strcpy(p->name,name);p->flt_num = flt_num;p->sit_num = sit_num;p->card = card;return p;
}void print_passager(void *pnode)
{struct passager *p = (struct passager *)pnode;printf("%s %d %d %c\n",p->name,p->flt_num,p->sit_num,p->card);
}struct flight * create_flight(int plane_name,char *src,char *dst)
{struct flight *p = malloc(sizeof(struct flight));if(NULL == p){return NULL;}p->plane_name = plane_name;strcpy(p->src,src);strcpy(p->dst,dst);return p;
}void print_flight(void *pnode)
{struct flight * p = (struct flight *)pnode;printf("%d %s %s\n",p->plane_name,p->src,p->dst);
}uav_t* creat_pthread(char *name,void *(*pfun)(void *))
{uav_t * thread = malloc(sizeof(uav_t));if(thread == NULL){perror("malloc fail\n");return NULL;}strcpy(thread->name,name);pthread_t tid;int ret = pthread_create(&tid,NULL,pfun,NULL);if(ret != 0){perror("pthread_create fail\n");return NULL;}thread->pfun = pfun;return thread;
}

创建航班节点

Klink_t *create_klink()
{Klink_t *pknode = malloc(sizeof(Klink_t));if(NULL == pknode){return NULL;}pknode->phead = NULL;pknode->clen = 0;pthread_mutex_init(&(pknode->mutex), NULL);return pknode;
}

 头插

int push_link_head(Klink_t *plink,void *p)
{Knode_t *pnode = (Knode_t *)p;pnode->pnext = NULL;pnode->ppre = NULL;pnode->pnext = plink->phead;if(plink->phead != NULL){plink->phead->ppre = pnode;}plink->phead = pnode;plink->clen++;return 0;
}

遍历

void klink_for_each(Klink_t *plink, void (*pfun)(void *))
{Knode_t *pnode = plink->phead;while (pnode != NULL){pfun(pnode);pnode = pnode->pnext;}printf("\n");
}

结构体的第一个成员的地址即为结构体的首地址

函数指针:指向函数的指针

指向函数的指针,它允许将函数作为参数传递给其他函数,或者将函数赋值给指针变量

函数:返回值 函数名(形参表)

去掉变量名剩下类型名-->

函数指针:返回值 (*函数指针名)(形参表);

使用:函数指针可以作为参数传递给其他函数,这在实现回调函数时非常有用

函数指针(实参)

例如,假设有一个返回 int 类型,接受两个 int 类型参数的函数,其对应的函数指针声明如下:

int (*func_ptr)(int, int);

指针函数:返回值为指针的函数

这是一种函数,它的返回类型是指针类型。这种函数调用结束后,返回一个指向某种数据类型的指针。在C语言中非常常见,尤其是在处理数组、字符串和动态内存分配时。

1、返回的指针指向的空间不能是一块临时的空间

(返回的指针不能指向一个局部变量的空间)

2、malloc

全局变量

静态变量

3、接指针函数的返回值的函数,最好判空

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com