这篇文章主要介绍“内核对象初始化链表组织方式是什么”,在日常操作中,相信很多人在内核对象初始化链表组织方式是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”内核对象初始化链表组织方式是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
在青河等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站制作、做网站 网站设计制作按需网站建设,公司网站建设,企业网站建设,成都品牌网站建设,营销型网站,成都外贸网站制作,青河网站建设费用合理。
最近在看RT-Thread内核的源码,内核对象使用链表组织。
RT-Thread内部有完整的【双向链表】与【单向链表】的操作API与实际用例
内核对象,内核派生的如线程、定时器、设备等,都是由链表链起来管理的。
/** * Double List structure */ struct rt_list_node { struct rt_list_node *next; /**< point to next node. */ struct rt_list_node *prev; /**< point to prev node. */ }; typedef struct rt_list_node rt_list_t; /**< Type for lists. */
链表是一种数据结构,跟其他的结构体类似,初始化后,本身占用内存空间,自身有内存地址。
一般双向链表,内部的成员,是链表本身结构体的指针,注意,指针的指向,初始化后,并没有确定。
RT-Thread 的双向链表,初始化时,内部的指针,指向自己本身的地址,也就是给链表的成员,赋好了初值(指针内容,一般是地址)。
链表使用,节点一般都是【全局结构体变量】,全局静态初始化,或动态内存申请(全局)。
不用全局的链表节点,注意不要链入链表结构,否则节点地址因为【生命周期】结束内存释放了,地址就不对了,就无法管理各个链表的节点了。
这里注要提一下链表节点的插入【次序】,因为遇到了一点小困惑,所以深入的研究了下。
理解:【最新节点】【前一个节点】【最早节点】
链表的头的问题:内核对象使用【对象容器】,全局的,对象初始化后,用了 rt_list_insert_after
/* 来自:object.c :rt_object_init */ /* insert object into information object list */ rt_list_insert_after(&(information->object_list), &(object->list));
注意,rt_list_insert_after,插入的位置,【不是链表的尾部插入,是第一个链表节点【第一个参数】的后面。】
也就是说,如果创建了3个内核对象,默认的排序如下:
不是:【容器head】 --- [obj1] --- [obj2] --- [obj2] 而是:【容器head】 --- [obj3] --- [obj2] --- [obj1]
如果把链表插入到【尾部】后面,就要先把链表指针移到尾部,再执行:rt_list_insert_after.
其实,thread,device等对象,都是内核对象【派生】出来的。
RT-Thread 提供list_thread、list_device等,查看内核的对象。
查看线程初始化【次序】,看看最后打印的线程,就是【最先】首个创建的线程。
一般从链表【头部】开始遍历各个链表节点。如下:最后一个节点是:main线程.
其实,main线程,是第一个创建的。
msh />list_thread thread pri status sp stack size max used left tick error -------- --- ------- ---------- ---------- ------ ---------- --- persim 16 suspend 0x000001ec 0x0000c000 08% 0x00000003 000 sens 28 suspend 0x000000d8 0x00001000 13% 0x00000019 000 hws 28 suspend 0x000000d8 0x00000800 10% 0x00000032 000 dcm_tpo 10 suspend 0x00000090 0x00000800 14% 0x00000004 000 dcm_tpo 10 suspend 0x00000090 0x00000800 14% 0x00000002 000 dcm_tpo 10 suspend 0x00000090 0x00000800 15% 0x00000004 000 tshell 20 running 0x000001fc 0x00001000 26% 0x0000000a 000 touch 16 suspend 0x00000098 0x00000800 18% 0x00000013 000 usbd 8 suspend 0x000000ac 0x00001000 04% 0x00000014 000 at_clnt 9 suspend 0x000000c0 0x00000600 12% 0x00000002 000 ulog_asy 30 suspend 0x00000084 0x00000c00 09% 0x00000006 000 mmcsd_de 22 suspend 0x000000a0 0x00000400 48% 0x00000014 000 alarmsvc 10 suspend 0x000000a8 0x00000800 27% 0x00000003 000 rils 12 suspend 0x000000b0 0x00000800 08% 0x0000001e 000 tidle0 31 ready 0x00000058 0x00000800 04% 0x0000001d 000 timer 4 suspend 0x00000074 0x00000800 08% 0x00000009 000 main 10 suspend 0x00000120 0x00000800 41% 0x00000012 000 /* 最先创建的线程,最后打印 */
内核对象初始化的链表【次序】:
到此,关于“内核对象初始化链表组织方式是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!