Android中的双向链表

Volcano在KubeCon 2026:云原生批量调度与AI基础设施的演进与实践 在云原生技术生态中,批量计算与AI工作负载的调度一直是个关键挑战。Kubernetes原生调度器为在线服务设计,难以满足分布式训练、大数据处理等作业对gang scheduling、队列优先级及异构资源(如GPU/NPU)的精细管理需求。Volcano作为云原生批量计算与AI基础设施的调度中间层,通过统一的Job、Queue和PodGroup抽象,为PyTorch、Spark、MPI等框架提供高效调度能力。本文从从业者视角,梳理Volcano在KubeCon + CloudNativeCon China 2 阅读详情

1.看源码必须搞懂Android的数据结构。在init源代码中双向链表listnode使用很多,它只有prev和next两个指针,没有任何数据成员。这个和linux内核的list_head如出一辙,由此可见安卓深受linux内核的影响的。本来来分析一下这个listnode数据结构。

这里需要考虑的一个问题是,链表操作都是通过listnode进行的,但是那不过是个连接件,如果我们手上有个宿主结构,那当然知道了它的某个listnode在哪里,从而以此为参数调用list_add和list_del函数;可是,反过来,当我们顺着链表取得其中一项的listnode结构时,又怎样找到其宿主结构呢?在listnode结构中并没有指向其宿主结构的指针啊。毕竟,我们我真正关心的是宿主结构,而不是连接件。对于这个问题,我们举例内核中的list_head的例子来解决。内核的page结构体含有list_head成员,问题是:知道list_head的地址,如何获取page宿主的地址?下面是取自mm/page_alloc.c中的一行代码:

page = memlist_entry(curr, struct page, list);

这里的memlist_entry将一个list_head指针curr换算成其宿主结构的起始地址,也就是取得指向其宿主page结构的指针。读者可能会对memlist_entry()的实现感到困惑。

#define memlist_entry list_entry

而list_entry定义则在include/linux/list.h中

135 /**
136 * list_entry get
the struct for this entry
137 * @ptr: the &struct list_head pointer.
138 * @type: the type of the struct this is embedded in.
139 * @member: the name of the list_struct within the struct.
140 */
141 #define list_entry(ptr, type, member) \
142 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

这样我们应该就明白了,curr是一个page结构内部成分list的地址,而我们所需要的却是那个page结构本身的地址,所以要从curr减去一个偏移量,即成分list在page内部的位移量。那么这个位移量怎么求?&((struct page*)0)->list就表示当结构page正好在地址0上时其成分list的地址,这就是所求的偏移量。

2.测试代码

#include<stdio.h>
#include<stddef.h>

typedef struct _listnode
{
        struct _listnode *prev;
        struct _listnode *next;
}listnode;

#define node_to_item(node,container,member) \
(container*)(((char*)(node))-offsetof(container,member))

//向list双向链表尾部添加node节点,list始终指向双向链表的头部(这个头部只含有prev/next)
void list_add_tail(listnode *list,listnode *node)
{
        list->prev->next=node;
        node->prev=list->prev;
        node->next=list;
        list->prev=node;
}
//定义一个测试的宿主结构
typedef struct _node
{
        int data;
        listnode list;
}node;

int main()
{
        node n1,n2,n3,*n;
        listnode list,*p;
        n1.data=1;
        n2.data=2;
        n3.data=3;
        list.prev=&list;
        list.next=&list;
        list_add_tail(&list,&n1.list);
        list_add_tail(&list,&n2.list);
        list_add_tail(&list,&n3.list);
        for(p=list.next;p!=&list;p=p->next)
        {
                n=node_to_item(p,node,list);
                printf("%d\n",n->data);
        }
        return 0;
}



深入理解Android中的LruCache缓存机制 每次访问缓存中的数据时,会将该数据移动到链表的头部,这样最近访问的数据就会位于链表的头部,而最久未访问的数据则会位于链表的尾部。当缓存已满并且需要添加新数据时,会将链表尾部的数据移除,以保持缓存的大小不超过设定的最大值。如果在多线程环境中使用LruCache,需要进行适当的同步操作,或者考虑使用线程安全的替代方案,如SynchronizedMap或ConcurrentHashMap。在上面的示例中,我们首先将一个键为"image1"的位图对象添加到缓存中,然后通过键"image1"从缓存中获取数据。 阅读详情

相关推荐

Android LRU缓存机制实战演示项目

在Android图像处理中,Bitmap是最典型的高内存消耗对象之一。其实际占用空间并非固定不变,而是受多种因素影响,包括分辨率、色彩格式、API版本及底层实现机制。因此,若要在中实现合理的内存控制,必须重写sizeOf()以返回真实的字节级开销。传统做法曾依赖来估算内存,这种方式虽能反映像素数据大小,但忽略了元数据、引用开销以及Dalvik/ART虚拟机的对象头成本。更为现代和推荐的方式是使用方法,它是SDK提供的标准化接口,用于返回位图像素数据所占的原始字节数。

weixin_31486261的博客 1064

node_to_item宏介绍

这个宏的在对链表进行操作,可以用如下图形表示: 这个宏的意思就是根据链表的地址转化为结构体的地址,以取得结构体中的数据。 其中listnode指链表结构,可以如下定义: typedef struct _listnode {     struct _listnode *prev;     struct _listnode *next; } listnode; node包含链表,

wangrl的博客 2696

toitem

托特姆

linux内核链表使用

Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p,如下: struct A{ int property; struct list_head p; } 其中,list_head结构类型定义如下: struct list_head { struct list_head *next,*prev;

达闻东的专栏 9137

Android双向表格可滑动可双向适配

本人根据一个网上的Demo改的,增加功能:设置表头,横向适配

全志T133-s3(Tina Linux)下RTL8723DS WiFi驱动移植与调试实战

本文详细介绍了在全志T133-s3平台(Tina Linux)上移植RTL8723DS WiFi驱动的完整流程,包括硬件连接、驱动源码获取、内核配置、系统适配、设备树配置以及常见问题排查。通过实战案例,帮助开发者快速解决SDIO接口通信、固件加载、电源管理等关键问题,实现稳定的WiFi功能。

weixin_30505225的博客 506

android启动过程的底层实现(三)

Android底层启动流程(三)之触发并启动Action和Service

weixin_43294087的博客 1099

尝试使用CubeMX做stm32开发之九:SYS配置

参考《STM32中文参考手册_V10》,研究CubeMX中有关SYS的配置

Forster-C的博客 9419

《Android的设计与实现:卷I》——第3章 3.5触发并启动Action和Service

3.5 触发并启动Action和Service init解析init.rc后,生成了存放Service和Action的链表。那么init又是如何控制这些Action和Service的呢?本节将详细分析这部分内容。 3.5.1 触发Action init解析完init.rc后,接着执行了action_for_each_trigger和queue_built...

weixin_34411563的博客 417

计算机三级考试嵌入式系统重点精简汇总

第一章 嵌入式系统概论 1.1.1嵌入式系统 (1)特点:(1)专用性;(2)隐蔽性;(3)资源受限;(4)高可靠性;(5)实时性;(6)软件固化。 (2)应用:(1)冰箱、洗衣机、电饭煲、空调、摄影机、DVD播放器等;(2)数控机床、飞机、汽车、电梯、X光机、血压计等;(3)电话机、传真机、打印机、pos机、GPS导航仪、路由器等。 1.1.2嵌入式系统组成与分类 (1)逻辑组成:硬件和软件,分为处理器、存储器、I|0设备与I|O接口,数据总线; (2)处理器:分为主处理器(CPU)和协处

chemkrik的博客 1万+

银河麒麟V10SP1系统盘瘦身指南:如何制作一个只含必需软件的轻量级安装镜像

本文详细介绍了银河麒麟V10SP1系统盘瘦身的完整流程,从依赖分析到最小化镜像构建,帮助用户创建只含必需软件的轻量级安装镜像。通过智能包筛选、KickStart定制和性能优化,显著减少ISO体积和部署时间,适用于服务器批量部署等场景。

weixin_26765287的博客 404

Android M 启动源码分析笔记之 - Zygote 孵化

【接上一篇的分析】 2、zygote到Home程序启动源码分析: 首先看服务执行入口函数: /* init进程的main函数服务启动代码段 */ int main(int argc, char** argv) { ... while (true) { if (!waiting_for_exec) { execute_one_

沉思 1475

海康威视工业相机SDK二次开发实战:多相机同步采集与图像存储

本文详细介绍了海康威视工业相机SDK二次开发实战,包括多相机同步采集与图像存储的优化方案。通过MVS软件搭建开发环境,实现硬件与软件触发同步采集,并提供高效的图像存储管理技巧,帮助开发者提升工业视觉项目的效率与稳定性。

weixin_29168813的博客 666

android中定义链表,Android中的双向链表

1.看源码必须搞懂Android的数据结构。在init源代码中双向链表listnode使用很多,它只有prev和next两个指针,没有任何数据成员。这个和linux内核的list_head如出一辙,由此可见安卓深受linux内核的影响的。本来来分析一下这个listnode数据结构。这里需要考虑的一个问题是,链表操作都是通过listnode进行的,但是那不过是个连接件,如果我们手上有个宿主结构,那当...

weixin_34620163的博客 481

YOLOv11改进 | 注意力篇 | YOLOv11引入CBAM注意力机制

我们的实验表明各种模型的分类和检测性能得到了一致的改进,证明了 CBAM 的广泛适用性。简单介绍:CBAM的主要思想是通过关注重要的特征并抑制不必要的特征来增强网络的表示能力。模块首先应用通道注意力,关注"重要的"特征,然后应用空间注意力,关注这些特征的"重要位置"。到此本文的正式分享内容就结束了,在这里给大家推荐我的YOLOv11改进有效涨点专栏,本专栏目前为新开的,后期我会根据各种前沿顶会进行论文复现,也会对一些老的改进机制进行补充,如果大家觉得本文帮助到你了,订阅本专栏,关注后续更多的更新~

tsg6698的博客 2万+

外骨骼机器人(五):步态分析之正常步态

研究病理步态之前,需要了解正常步态,作为判断标准。但是需要记住两个问题:1.“正常”因人而异,性别、年龄、身体情况都需要考虑在内,因此,需要对不同的个体选择合适的正常标准;2.即使病人的步态与正常步态有某种不同,这也不能说明这是不可取的,也不能说明应该把它变成“正常”步态。许多步态异常是对病人的一些问题的一种补偿,尽管异常,但它们仍然是有用的。步态周期的定义是连续为两次发生重复行走事件之间的时间间隔。尽管可以选择任何事件来定义步态周期,但通常使用一只脚接触地面的瞬间(“初始接触”)是方便的。

行者无疆的博客 1991

android中定义链表,android源代码学习 init中的双向链表listnode

在init源代码中双向链表listnode被使用地很多。android源代码中定义了结构体listnode,奇怪的是,这个结构体只有用于链接节点的prev和next指针,却没有任何和”数据“有关的成员变量。那么代码中如何通过一个节点来找到该节点“存储“的数据呢?关键是下面这个宏。#define node_to_item \(container *) (((char *) (node)) - off...

weixin_28978471的博客 290

Trae+雪球MCP,化身专业的股票分析师(玩转100个MCP系列第二弹)

大家好呀,我是程序员夏叶,深度AI编程使用者,专注于分享AI编程方面的使用技巧、经验以及前沿资讯,有兴趣的可以关注我的公众号,一起学习,共同进步。第二弹,使用Trae+雪球MCP,获取股票实时行情,分析股票走向等,写代码间隙看看股票价格,研究研究行情,哈哈。真的很不错呀,最关键的是,足够隐蔽,同事以为你在写代码,实际你在浏览股票行情,哈哈,感兴趣的可以试一下哦。说实话,沧州明珠这只股我算是砸手里了,不过还好买的不多,哈哈。

cpp加油站的专栏 517

android源代码学习 init中的双向链表listnode

在init源代码中双向链表listnode被使用地很多。android源代码中定义了结构体listnode,奇怪的是,这个结构体只有用于链接节点的prev和next指针,却没有任何和”数据“有关的成员变量。那么代码中如何通过一个节点来找到该节点“存储“的数据呢?关键是下面这个宏。 ? 1 2 #define node_to_item

小tsan的专栏 1742

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

C++之双向链表与哈希链表用法区别实例(二百六十八)

本篇目的:在阅读Linux内核代码时,发现Binder驱动中的双向链表和哈希链表的挺有意思,分享给大家。在Android的Binder区域中,双向链表(struct list_head)和哈希链表(struct hlist_node)是两种不同的数据结构,它们在实现中有一些区别和各自的作用。首先,让我们了解这两种数据结构的基本概念:双向链表(struct list_head)双向链表是一种数据结构,其中每个节点都包含指向前一个节点和后一个节点的指针。这使得在双向链表中,节点可以双向遍历。

Android系统攻城狮 1057

老版QQ原生表情gif动态

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

Android技能树 — 数组,链表,散列表基础小结

当我们去看电影的时候,我们知道电影院门口会有一个储物柜,上面还会有连续的数字,一个抽屉连着一个抽屉。然后你就会把你的东西放在相应号码的小抽屉中,然后进去看电影了。

keyoukewude的博客 984

Android随笔-LRU 缓存的底层数据结构详解

LRU缓存数据结构解析 摘要:LRU(最近最少使用)缓存策略通过HashMap和双向链表组合实现高效操作。HashMap提供O(1)的快速查找,双向链表维护访问顺序。当缓存满时,淘汰链表尾部的最久未用数据。双向链表支持O(1)的节点移动和删除,解决了单向链表尾部操作效率低的问题。Java中的LinkedHashMap已内置LRU功能,通过设置accessOrder和重写removeEldestEntry即可快速实现。这种数据结构组合完美平衡了查找速度和顺序维护的需求,是LRU策略的高效实现方案。

古典码 107

【阿里P8大牛教你Android入门之路(java篇)】Java集合——LinkedHashMap(系列篇5)

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。还有。

2301_76327109的博客 743

Android LruCache 缓存机制实现原理

通过使用 LruCache, 查看 LinkedHashMap 源码, 分析 LRU 算法的具体实现细节. LRU 算法描述 当序列达到设置的内存上限时, 丢弃序列中最近最少使用的元素. LruCache Android SDK 提供的使用了(Least Recently Used)最近最少使用算法的缓存类. 编写一个 LruCache, 用于缓存 Integer. public clas...

道阳 239

Android笔记 - Binder之数据结构(一)

程序等于算法加数据结构,这句话很贴切 Binder 程序。Binder 的数据结构设计很精巧,了解它们对了解整个 Binder 通信机制很有帮助。 在 Binder 驱动程序中,有两种类型的数据结构,第一种是 Binder 驱动内部使用的数据结构,第二种是 Binder 驱动以及用户空间都可以使用的数据结构。

yansha的专栏 1229
上一篇: 安卓模拟器中运行C程序
下一篇: Android的init过程:init.rc解析流程
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值