rt-thread的位图调度算法分析

序言期待读者本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语句不会介绍,但是并不要求读者有过多的C基础,比如指针和链表等不会要求太多,后面在分析代码时,会附带地介绍相关的知识,如果您已经精通了C语言的指针则可以略过相关的介绍。除此之外,不再假设读者拥有任何知识。如何阅读代码就以rt-thread内核代码为例(注,指rt-thread的kernel代码),
摘要由CSDN通过智能技术生成

序言

期待读者

本文期待读者有C语言编程基础,后文中要分析代码,对其中的一些C语言中的简单语句不会介绍,但是并不要求读者有过多的C基础,比如指针和链表等不会要求太多,后面在分析代码时,会附带地介绍相关的知识,如果您已经精通了C语言的指针则可以略过相关的介绍。除此之外,不再假设读者拥有任何知识。

如何阅读代码

就以rt-thread内核代码为例(注,指rt-thread的kernel代码),大约有8500行代码。直接阅读显然是很容易陷入代码中的。所谓工欲善其事,必先利其器,我推荐使用下面的工具来阅读。

  • MDK/IAR/其他集成开发环境,最好支持软件仿真,我使用MDK4.0
  • 强大的代码阅读软件source insight
  • 一个笔记本,随时用来记录自己的一些想法,感悟,或者困惑

首先使用source insight创建一个rt-thread的工程,然后开始代码阅读。关于source insight的使用,暂不赘述。建议读者自行google source insight教程。

一切就绪有以后,面对浩如烟海的代码(8500行),从哪里开始下手呢?我的建议是, 先阅读工程中的头文件开始,然后阅读C文件。之所以采用这种阅读方式,是c代码中用的数据结构通常定义在.h的文件中。了解一个程序,首先先要了解这个程序所使用的数据结构。同样,在阅读C文件时,如果其中定义了数据结构,比如定义了某些结构体等,则先阅读它门。

rt-thread的内核调度算法

rt-thread的内核调度算法采用位图(bitmap)的调度算法。这个算法的好处是可以实现O(1)调度(注,O(1)定义,请参考《数据结构与算法分析》),大致来说,就是每次调度的时间是恒定的:无论当前的系统中存在多少个线程,多少个优先级,rt-thread的调度函数总是可以在一个恒定的时间内选择出最高优先级的那个线程来执行。

rt-thread内核调度算法涉及的源码文件主要是scheduler.c

《rt-thread编程指南》中已经大致介绍了,rt-thread的调度算法为基于优先级调度和基于时间片轮转调度共存的策略。这里再重复一下,rt-thread内核中存在多个线程优先级,具体的级别数目可以在rt_config.h中以宏定义的方式配置。而且rt-thread支持多个线程具有同样的线程优先级 。

当系统存在多个线程时,可能的情况是,某些线程具有不同的线程优先级,但是还有一些线程具有相同的优先级。对于这种情况,rt-thread采用的调度策略是,对不同优先级的线程,采用可抢占的方式:即高优先级的线程会“立刻”抢占低优先级的线程,而对同线程优先级别的多个线程则采用时间片轮转的方式。

在上面的情形中,摆在rt-thread面前的问题就,如何从多个线程优先级别中找出当前优先级最高的那个线程,并调度执行。

线程结构存储

实际上,寻找当前线程优先级最高的线程并调度执行,首先需要解决线程数据结构的存储问题。下面先来分析,rt-thread中如何存储多个线程的数据结构。

现在让我们做几点说明:

  • 每一个线程的信息用线程控制块来表示,线程控制块,即Thread Control-Block,缩写为TCB,它是在rtdef.h中定义一个struct结构体,这个结构体的作用就是用来描述一个线程所有必要信息。
  • 线程的优先级别用非负整数(即无符号整数)表示,并且优先级越高,对应的数越小
  • 系统的线程优先级的数目固定,最多支持256级
  • 系统中的线程数目不做任何限制,线程的数目仅受限于系统RAM的大小。 重点来考虑最后两点,我们来思考一下,当系统存在多个的线程时,也就是说会有多个TCB时,我们怎么来“排列”或者存储这些TCB,才能实现上面的这两点要求?

线程的优先级别数目固定,显然我们可以使用一个数组来定义,数组的长度即为线程优先级的数目,数组的每个元素为一个指向TCB形数据结构的指针。即,我们定义了一个指针数组。

线程数目不受限制,那当某个线程优先级上存在多个线程时,这些TCB显然没办法存储在上面定义的数组对应的优先级位置上,我们使用链表来解决这个问题,链表是一种数据结构,每个元素彼此链接,TCB中有一个链接下一个TCB的“链表数据结构”,如同一个钩子一样。

这样我们就可以达到上面提及的两点设计要求,不同线程优先级的线程的TCB分别存在线程TCB数组对应优先级的位置上。对于相同优先级别的多个线程,我们只需要将该优先级的第一个就绪线程的TCB存储在线程TCB数组中相关位置,后续同级线程通过链表依次连接。

scheduler.c 中

  • 16
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值