从著名的list_head看linux内核中OO

大模型学习笔记四:LangChain开发框架解析 1、模型I/O封装LLMs:大语言模型Chat Models:一般基于LLMs,但按对话结构重新封装PromptTemple:提示词模板OutputParser:解析输出2、数据连接封装Document Loaders:各种格式文件的加载器Document transformers:对文档的常用操作,如:split,filter,translate,extract metadata,etcTextr Embedding Models:文本向量化表示,用于检索等操作。 阅读详情

如果有人问我最欣赏linux 的什么,我会毫不犹豫地回答:list_head 。这个小小的结构向世人说明了用c 语言写成的linux 内核也在实现着OO ,下面我就具体来说一下下。先看list_head

struct list_head {

         struct list_head *next, *prev;

 };

就 这吗?就这!你别看它小,它却可以充当任何在内核中存在的东西,几乎所有的内核管理设施都用到了它,用OO 的语言讲就是它作为基类,几乎所有的内核设施都 继承了它,OO 中一直争论不休的就是用继承还是用包含,“ 遗憾” 的是,linux 内核利用list_head 将这两者集成在了一起,让人叹为观止!举几个 例子:

struct tast_struct{

     ...

     list_head tasts;

     ...

};

struct sched_entity {

         ...        

         struct rb_node          run_node;

         struct list_head        group_node;

};

仅此二例就可以说明list_head 可以作为task_struct 还可以作为sched_entity. 这仅仅是单向的转化,可以说sched_entity 继承了list_head ,也可以说tas_struct 继承了list_head ,那么到底是谁呢?需要的时候怎么转化过来呢?这个一会再说,先说说这 么做的意义,众所周知,继承的意义就是子类可以有父类的行为,还有自己的行为,那么list_head 的行为是什么呢?链表嘛,就是插入,删除,查找,再 问一个,内核数据结构作为子类为何要以拥有这些操作的list_head 作为它们的父类呢?原因就是提取公因子的结果,想想看,task_struct 是 管理进程的,net_device 是管理网卡的,这些能有什么一样的地方,要认识到这是在内核里面,内核的功能就是管理一切,正是需要被管理对象的注册, 注册的结构都要放到链表里面,于是几乎所有的数据结构都需要链表的操作,这样天经地义的继承list_head 就没有什么问题了,下面看看怎么取出原对 象,这也就是多态的概念范畴了,list_head 到底是什么样的对象呢?

#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) );})

上面的代码只要你懂c 语言,并且指针玩得好,一眼就看懂了,举个例子巴:

inode *inode ;

struct list_head * tmp = next; 

inode = list_entry(tmp, struct inode, i_sb_list);

这里只有一个list_head ,但是我们需要的是一个inode ,那么调用list_entry 就可以取到inode 了,什么意思呢?就是说inode 结构的i_sb_list 字段表示一个list_head ,现在有了list_head ,那么此list_head 此的地址减去i_sb_list 相对于inode 结构的偏移就是inode 结构体了,其实现代的面向对象语言底层实现机制也是这样的,只不过偏移相对固定,比如c++ 语言中的类的对象在 内存中的布局就是把基类放到这个对象固定偏移的地方,根据编译器不同这个位置也不同,很一般的就是基类放到最前面,以下才是子类私有的数据,linux 内 核和现代c++ 语言如出一辙,至于java ,本质上也是这样,只不过没有c++ 那么直观罢了,java 的对象由jvm 创建并由jvm 管理,看看jvm 的源 代码就知道了,我看过一些,jvm 管理对象的方式和linux 内核的实现更加相似一些。但是这里的list_entry 并没有进行类型检查,这实际上是不 必要的,它可是内核啊,出了问题崩溃掉自然比强行恢复要好得多,再者说一般人接触不到内核,再内核的调试阶段问题几乎就都解决了,如果还有问题只好听老天 安排了,内核中少了类型检查会节省很大一笔开销的,另外一个更有意思并且更有意义的原因就是保持最简单最天真的形式,这样黑客就不会想方设法去避开类型检 查了,因为压根就没有检查,如果你有问题,那么很简单,直接崩溃,不给黑客任何可乘之机,这印证了一条哲理:只要有检查,总能避开,最简单的方式就是最好 的方式,最危险的反而最安全!
    
内核中不光实体设施用了list_head ,就连另外的管理设施也用,比如klist

truct klist {

         spinlock_t              k_lock;

         struct list_head        k_list;

         void                    (*get)(struct klist_node *);

         void                    (*put)(struct klist_node *);

 };

struct klist_node {

         struct klist            * n_klist;

         struct list_head        n_node;

         struct kref             n_ref;

         struct completion       n_removed;

 };

如果说刚才的论述令你不知所云的话,这两个应该比较简单了,毕竟它们都是list ,一个klist 继承list_head 从字面意义上讲要比一个task_struct 继承list_head 好理解得多。
    
最后谈一下继承和包含,就以klist 为例吧,你说klist 继承一个list_head 呢还是包含一个list_head 呢?实际上都是,为什么这么说呢?要明确list_head 可以代表klist 自身,因为可以用list_entry 转化,我们说list“ 是” 一个list_head ,这个意义上就是继承,但是另一方面,一个klist 确实“ 有” 一个list_head ,就像结构中写的那样,list_head 确实是klist 的一个字段,这里list_head 不是作为一个klist 存在,而是作为一个真实的链表存在,这个意义上讲,klist 包含一个list_head ,有点文字游戏了,呵呵!linux 总是在人们争论不休的问题两端之间游走,有种行走于江湖的味道,这往往让一些人不知所措,谁让它的创始人长得那么滑稽呢?呵呵!

 

在C++中,NULL和nullptr有什么区别? 这两个定义导致了冲突,C++中的NULL如果和C语言一样也是(void *)0指针,而C++不允许void*隐式转换成其它指针类型,那NULL就无法表示空指针了。因此,使用 nullptr可以增加代码的清晰性,避免类型安全问题。即使在混合C++和C代码时,nullptr也提供了一个明确无误的空指针表示,达到兼容的目的。C++11 引入 nullptr 彻底解决了这些问题,提高语言的安全性、清晰性和现代性。在了解NULL和nullptr背后的故事之后,相信大家以后再也不会用NULL了。 阅读详情

相关推荐

直流无刷减速电机选型指南:从KV值到霍尔传感器,新手必看的5个关键参数

本文详细解析直流无刷减速电机选型的5个关键参数,包括KV值、转矩、电流与功率、减速比选择以及霍尔传感器配置。通过实战案例和避坑策略,帮助工程师精准匹配电机性能与负载需求,提升工业自动化设备的可靠性和效率。特别强调霍尔传感器在精准控制中的关键作用。

alice7model的博客 620

从著名的list_head看linux内核中OO && 从Unix分层内核栈以及中断处理看Linux内核的另类

如果有人问我最欣赏linux的什么,我会毫不犹豫地回答:list_head。这个小小的结构向世人说明了用c语言写成的linux内核也在实现着OO,下面我就具体来说一下下。 先看list_head struct list_head {          struct list_head *next, *prev; }; 就 这吗?就这!你别看它小,它却可以充当任何在内核中存在的东西,几乎所...

~~ LINUX ~~ 309

20231126-超详细Isaac Gym安装教程(基于双系统版本)

我一开始使用了WSL2虚拟环境试了集群服务器里面的交互式桌面,但是都失败了,WSL2因为没办法调用系统的GPU,应该有办法配置但我放弃了,感兴趣的可以自己探索(图片贴出来了)。服务器上出现的问题是Segmentation fault (core dumped),目前还没解决,有可能是驱动和cuda版本的问题(后面有时间再解决)等上图右边都达到了100%,就创建了一个名为rlgpu的conda环境,然后会出现success。注意安装版本要低于3.9!参考链接:非常详细,大家直接看这个博主的安装就行。

m0_37802038的博客 2万+

专业 英语

计算机、数学、机械等专业的专业英语词汇

Edward2022的博客 2944

时间序列分析:ARCH、GARCH、TGARCH与DCC-GARCH波动率模型(含代码)

关注TGARCH模型和DCC-GARCH的应用,通过在沪深300和中证500指数上应用TGARCH和DCC-GARCH模型,揭示这两个指数之间的条件异方差及动态相关性的变化规律。

celiaweiwei的博客 1万+

DCA决策曲线的解读和代码实现

0.决策曲线 决策曲线分析法(Decision Curve Analysis,DCA)是个与ROC曲线相提并论的相对比较新的模型评价方法。 关于它的原理,长篇大论的医学统计学知识解读实在不是我的强项,放上两个链接偷偷懒: https://www.plob.org/article/12455.html https://www.iikx.com/news/statistics/1622.html 如果想看文章,这篇里的fig7就是:https://www.ncbi.nlm.nih.gov/pmc/artic

weixin_42960896的博客 1万+

list

的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。,因此反向迭代器的实现可以借助正向迭代器,即:反向迭代器内部可以包含一个正向迭代器,对正向迭代器的接口进行包装即可。是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。迭代到该位置,在这段位置上迭代需要线性的时间开销;最大的缺陷是不支持任意位置的随机访问,比如:要访问。还需要一些额外的空间,以保存每个节点的相关联信息。个元素,必须从已知的位置。

xie0510_的博客 268

本地部署DeepSeek-Coder-6.7B 离线版的完整指南:打造适配当前系统的AI助手

《DeepSeek-Coder-6.7B本地部署指南》详细介绍了如何离线部署这款专注于代码生成的AI模型。文章涵盖硬件要求(推荐8核CPU、32GB内存、NVIDIA RTX3080显卡)、软件依赖(Python3.8+、CUDA11.0+、PyTorch1.9+)以及具体安装步骤,包括模型下载、路径配置和GPU加速设置。重点说明如何通过输入系统配置文档和使用说明书,让模型生成适配特定系统的代码,并提供了参数调优和模型微调的方法。该指南旨在帮助开发者在本地安全高效地使用AI助手,实现代码自动生成与优化,提升

欢迎来到我的优快云博客!我专注于技术创新和数字化转型,特别是在低代码平台、人工智能和大数据分析领域的探索与应用。通过深入分析各种行业案例,帮助企业加速数字化进程,提升运营效率与创新能力。在这里,您将找到关于低代码平台、AI技术、数据分析与 1492

Java 集合框架(List、Set、Map)与常用基础

本文整理Java集合框架核心知识,涵盖集合体系、Collection接口API、List(ArrayList、LinkedList、Vector)、Set(HashSet、TreeSet)、Map(HashMap、TreeMap、Hashtable)实现类原理、泛型、增强for循环、可变参数与工具类,并附核心易错点速查表。

既然你都点开这里了,那可以给我点个关注吗?可以吗?可以吗? 483

PyTorch深度学习项目实战100例数据集

最近很多订阅了的用户私信咨询有些数据集下载不了以及一些文章中没有给出数据集链接,为了解决这个问题,专门开设了本篇文章,提供数据集下载链接,打包100例的所有数据集。本专栏适用人群:深度学习初学者,专栏将具体讲解如何快速搭建深度学习模型用自己的数据集实现深度学习小项目。 本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。

优快云 精品推荐 2万+

【蓝桥杯单片机组第八届省赛】— 基于单片机的电子钟程序设计与调试

1、初赛试题 1.1 基本要求 (1)使用 CT107D 单片机竞赛板, 完成“电子钟” 功能的程序设计与调试; (2)设计与调试过程中,可参考组委会提供的“资源数据包”; (3)Keil 工程文件以准考证号命名, 完成设计后, 提交完整、 可编译的 Keil工程文件到服务器。 1.2 硬件框图 1.3功能描述 1.3.1 初始化 (1)关闭蜂鸣器、继电器等无关外...

Fanjufei的博客 3661

Bugku 326 Baby-heap1 题解:glibc 2.23 堆溢出到 FSOP 劫持 _IO_list_all(附完整 exp)

为什么 FSOP 在 2.23 这么好用?glibc 2.23 的_IO_FILE虚表调用没有 vtable 合法性检查是 2.24 才加入的),只要能把指向自己伪造的 FILE,就能让__overflow槽位指向任意函数。exit()一定会走因此把_mode置 0、置 1、置 0,就能进入;把fp首地址写成/bin/shsystem(fp)的参数就齐了。为什么用 fastbin attack 而不是?2.23 没有 tcache,fastbin 的fd。

kingx3的博客 183

YOLOv8改进策略【独家融合改进】| StarNet + 小目标检测头,加强跨尺度的上下文特征融合,提高小目标检测能力

P3/8 - small检测头原始模型中的P3/8特征层对应的检测头主要用于检测相对较小的目标。其特征图大小相对较大,空间分辨率较高。适合检测尺寸大概在8x8到32x32像素左右的目标。P4/16 - medium检测头这个检测头对应的P4/16特征层经过了更多的下采样操作,相比P3/8特征图空间分辨率降低,但通道数增加,特征更抽象且有语义信息。它主要用于检测中等大小的目标,尺寸范围大概在32x32到64x64像素左右。P5/32 - large检测头P5/32。

Limiiiing的博客 635

[C++]:7.STL:list

好久不见,firdawn小课堂又和大家见面啦。今天我们要学习的内容是list容器,list也是一种常用的数据结构。下面是本章的思维导图,那么让我们开始学习吧!自定义的list,由三个结构构成。分别是链表的最小组成单位,也就是链表节点。以及迭代器类和list类其实要特别说明的是, List的迭代器,它不是单纯的指针,因为我们如果对指针直接进行解引用操作的话,我们得到的是这个节点,而不是节点里面存储的值并且我们对这个指针加加,得到的也不是下一个节点的地址,而是所在节点的下一个单位的地址。

2301_80817679的博客 176

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

LinkedList知识

LinkedList是List 接口的实现类,同时实现了Deque有序、可重复、带索引双向链表prev前驱指针 + item数据 + next后继指针✅ 核心特点首尾增删速度快:只修改指针,不需要移动元素查询慢:没有数组随机访问,按索引查找需要遍历链表线程不安全,支持存储 null兼具 List、队列、栈的功能,所以有两套首尾 API(一组抛异常,一组返回 null)ArrayList:可变数组 → 查询快,中间增删慢LinkedList:双向链表 → 首尾增删快,查询慢多态写时,

Sarvartha的博客 88

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Iterator 迭代器、ListIterator & foreach 循环

foreach 是简化版 for 循环,底层依然是 Iterator 迭代器(语法糖)适用范围:数组、所有实现Iterablefor(容器中元素类型 临时变量 : 容器变量) {执行语句hasNext()只判断,不移动指针;不能连续多次调用next(),容易泛型缺失时,Iterator 取出元素是 Object,需要强制转换只能 List 获取,Set 集合不能使用增强 for 只是语法糖,编译后依然变成 Iterator,同样不能在遍历时直接调用集合增删方法。

Sarvartha的博客 347

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

List 接口 & ArrayList

List 是Collection 的子接口(单列集合)有序:存入顺序和取出顺序一致可重复:允许存储重复元素有索引:支持根据索引操作元素(这是 List 独有的!Set 没有索引)所以 Collection 里所有方法,List 全都可以用,同时 List 新增一套带索引的专属方法ArrayList 是实现类,实现了 List 接口有序、可重复、有索引底层数组,查询快、中间增删慢扩容 1.5 倍;空参构造不会立刻创建长度 10 数组,JDK8 是懒加载线程不安全,不同步。

Sarvartha的博客 345

一个链表(Linked List)--为什么要用链表--deepseek

数组(如你定义的大盘子就像你在 FPGA 里例化了一块深度为 2500 的 BRAM。它必须是一块连续的、完整的内存。如果内存里全是碎片,凑不出 2500 个连续空位,数组就建立不起来。链表(Linked List)就像一堆散落在大街小巷的小仓库,每个仓库大小不固定,彼此不挨着。但是,每个仓库的门口都贴了一张小纸条,纸条上写着“下一个仓库的地址”。我们来画个图,这就是链表的核心——节点(Node)text。

AlibabaApple的博客 164

FreeRTos笔记(12c):从事件链表里删除节点 xTaskRemoveFromEventList、

(1) (2) 谢谢

zhangzhangkeji的博客 161

【C++初阶】list使用及相关实现,思路顺滑流畅!

list使用及相关实现

Severus_black的博客 154

List(上):LPUSH / RPUSH 与 LRANGE

这是《Redis C++ 实战笔记》系列的第 06 篇。String 讲完了,进入第二种类型:List。它是一串有顺序、可以重复的值,两头都能进出。

wbs_scy的博客 234

细粒度锁的线程安全list实现

【代码】细粒度锁的线程安全list实现。

weixin_43698578的博客 191

TypeError: must be str, not list

【代码】TypeError: must be str, not list。

Forerunner and Successor 先駆者と後継者 40
上一篇: 从文件系统看系统架构
下一篇: 从古老的System V进程调度器说开去
linuxcode_turing
博客等级 码龄17年 0粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值