首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux通用链表

引言 链表的实现是基于结构体与指针两者实现的,常用的链表数据结构如下: //将int起别名ELEMTYPE,是为了方便修改链表中的数据域类型。...在Linux中设计了一种适合于各种类型数据域都可以使用的通用型链表: struct list_head { struct list_head *prev, *next; }; 摒弃掉数据域,只保留头尾指针...Linux中在声明中抛弃了数据域,也就解决掉了这一问题。 原理 Linux使用链表的方法:使用时,自定义结构体包含数据域+链表结构体。...即让内部链表成员与其他链表成员构建成双链表,实现遍历寻址,然后通过链表成员找到包含该成员的结构体首地址。 ?...「linux实现获取结构体首地址:」 #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&(

1K20

linux内核里的字符串转换 ,链表操作常用函数(转)

1.对双向链表的具体操作如下: list_add ———向链表添加一个条目   list_add_tail ———添加一个条目到链表尾部   __list_del_entry ———从链表中删除相应的条目...———从一个列表中删除并加入为另一个链表的尾部   list_is_last———测试是否为链表的最后一个条目   list_empty———测试链表是否为空   list_empty_careful—...将链表一分为二   list_splice———将两个链表进行合并   list_splice_tail———将两个链表进行合并为一个链表   list_splice_init———将两个链表进行合并为一个链表并初始化为空表...———反向遍历链表   list_for_each_safe———遍历链表并删除链表中相应的条目   list_for_each_prev_safe———反向遍历链表并删除链表中相应的条目   list_for_each_entry...———继续遍历链表并删除链表中相应的条目   list_for_each_entry_safe_from———从当前点遍历链表并删除链表中相应的条目   list_for_each_entry_safe_reverse

2.2K20
您找到你想要的搜索结果了吗?
是的
没有找到

C 链表 - linux 如何实现

链表是基本数据结构, 一开始学习数据结构时, 我一般这么定义, 对应实现从头或尾插入的处理函数, struct int_node_old { int val; struct int_node_old...list->next); list->next = new; new->next = NULL; } 但是发现, 如果这么定义的话,每次实现一个list的结构, 都需要重新对应编写处理函数...查看linux的源码, 发现linux中也为我们提供了相似的实现(源码), 把一些共性统一起来。 类是 python 中for_each处理,有些意思。...linux 下的链表定义在文件 include/linux/types.h, 采用的是双向列表 struct list_head { struct list_head *next, *prev;...list 利用这个定义, 我定义了一个自己的list数据结构, 并copy了一些接口实现,感受下,linux 是如何管理链表的。

2.7K30

linux内核源码 -- list链表

linux kernel中的list估计已经被各位前辈们写烂了,但是我还是想在这里记录一下; linux kernel里的很多数据结构都很经典, list链表就是其中之一 本篇要介绍的内容: list...的定义 list提供的操作方法 注意事项 使用实例 ---- List 所在文件: List的所有操作可以在 include/linux/list.h找到; List head的定义可以在 include.../linux/types.h找到; 定义 实际上这就是一个双向循环链表, 且有一个头指针 list head的定义: struct list_head { struct list_head *next...WRITE_ONCE(list->next, list); list->prev = list; } 插入操作 将一个元素插入到两个元素之间, 即将 new插入到prev和next中, 这个函数是下面在头部和尾部插入的实现基础...new, struct list_head *head) { __list_add(new, head, head->next); } 在尾部插入,在最后一个元素间和头指针间插入, 因为是循环链表

2.3K10

Linux 内核 内存管理】RCU 机制 ③ ( RCU 模式下添加链表项 list_add_rcu 函数 | RCU 模式下删除链表项 list_del_rcu 函数 )

文章目录 一、RCU 模式下添加链表项 list_add_rcu 函数 二、RCU 模式下删除链表项 list_del_rcu 函数 一、RCU 模式下添加链表项 list_add_rcu 函数 ---...- 在 Linux 源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 , 其中定义的 static inline void list_add_rcu...(struct list_head *new, struct list_head *head) 函数 , 就是 向 链表中 添加元素 的 函数 ; list_add_rcu 函数中 , 主要是调用了 _...-5.6.18\include\linux\rculist.h#105 二、RCU 模式下删除链表项 list_del_rcu 函数 ---- 在 Linux 源码 linux-5.6.18\include...函数 , 就是 从 链表中 删除元素 的 函数 ; list_del_rcu 函数中 , 主要是调用了 __list_del_entry 函数 , 在 __list_del_entry 函数中 , 又调用了

80130

Linux 内核通用链表学习小结

描述 在linux内核中封装了一个通用的双向链表库,这个通用的链表库有很好的扩展性和封装性,它给我们提供了一个固定的指针域结构体,我们在使用的时候,只需要在我们定义的数据域结构体中包含这个指针域结构体就可以了...传统的链表结构 struct node{ int key; int val; node* prev; node* next; } linux 内核通用链表库结构 提供给我们的指针域结构体...反推结构体首地址 举个例子 这个例子包括简单的增、删、遍历 #include #include #include <linux...student)*5,GFP_KERNEL);//向内核申请5个student结构空间 memset(pstudent,0,sizeof(struct student)*5); //清空,这两个函数可以由...内核提供的这个通用链表库里面还有很多其他的接口,这里没有详细的一一举例,有兴趣的可以自己去看看,在源码包 include/linux/list.h 文件里面,不过通过阅读一些源代码确实对我们也有很大的提高

1.2K21

Linux 内核 内存管理】RCU 机制 ④ ( RCU 模式下更新链表项 list_replace_rcu 函数 | 链表操作时使用 smp_wmb() 函数保证代码执行顺序 )

文章目录 一、RCU 模式下更新链表项 list_replace_rcu 函数 二、链表操作时使用 smp_wmb() 函数保证代码执行顺序 一、RCU 模式下更新链表项 list_replace_rcu...函数 ---- 在 Linux 源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 , 其中定义的 static inline void...list_replace_rcu(struct list_head *old, struct list_head *new) 函数 , 就是 更新 链表元素 的 函数 ; list_replace_rcu...-5.6.18\include\linux\rculist.h#198 二、链表操作时使用 smp_wmb() 函数保证代码执行顺序 ---- 编译器 和 CPU 优化 代码时 , 有时会将 代码执行顺序改变..., 在链表操作时 , 代码的执行顺序必须得到保证 , 否则会得到不可预知的结果 ; 使用 smp_wmb() 函数 , 可以保证该函数 前两行 的代码 执行完毕后 , 再执行后两行的代码 ;

75020

linux中getchar函数用法,linux getchar函数使用

1 函数介绍 1) 函数原型 int getchar(void); 2) 函数功能 从stdin中读取一个字符。 3) 返回值 返回读取字符的ASCII值或者EOF字符或者出错值。...4) 头文件 #include 2 函数使用 2.1 getchar函数的特点 Linux下编写的一个例子: #include int main(void) { char ch; int num...重新编译并运行程序,输入字符串:hello[回车] 得第一次运行结果 当程序首次执行到while中的getchar时,getchar函数等待用户的输入,getchar函数一直等待用户输入,当用户按下回车表示用户输入完毕...getchar函数读取,因为while循环的条件已经为假)并得到以下输出界面 String输入字符串的长度为6在一次表明getchar读取了用户输入的回车。...3 额外总结 函数本身的特性与语句条件限制两者各自带来的作用需要分清楚。 Note Over。 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。

3.1K30

Linux C 数据结构 ->单向链表

简介   链表Linux 内核中最简单,最普通的数据结构。...这时,就引入了头结点   的概念,头结点和其他节点数据类型一样,只是数据域为NULL,head->next = NULL,下面   我们看一个创建空链表函数,如何利用头结点来创建一个空链表,只要头节点在...链表基本运算的相关"算法"操作 or 操刀(~烹羊宰牛且为乐,会须一饮三百杯~)   链表的运算除了上面的创建空链表,还有数据的插入,删除,查找等函数链表的运算有各种实现方   法,如何写出一个高效的...,封装性较好的函数是我们要考虑的,比如数据插入函数,我们就要尽可能   考虑所有能出现的结果,比如:1)如果需插入数据的链表是个空表;2)所插入的位置超过了链表的   长度;如果我们的函数能包含所有能出现的情况...,   *则接到尾节点的后面,同样,这样适用于{ }即空链表,这样   *我们可以建立一个空链表,利用这个函数,实现链表的初始化   */   node_prev->next = node_new

1K00

1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() { s1 :=... (1)双向链表的结构 ?...  双向链表的缺点  链表增加了元素的指针域,空间开销比较大 遍历时跳跃性查找内容,大量数据遍历性能低  (2)双向链表容器List 在Go语言标准库的container/list包提供了双向链表List...双向循环链表和双向链表区别 双向循环链表没有严格意义上的头元素和尾元素 没有元素的前连接和后连接为nil 一个长度为n的双向循环链表,通过某个元素向某个方向移动,在查找最多n-1次,一定会找到另一个元素...(2)在container/ring包下结构体Ring源码如下 官方明确说明了Ring是循环链表的元素,又是环形链表 实际使用时Ring遍历就是环形链表第一个元素 // A Ring is an element

77430
领券