就绪表
- 适用于理解ucosII任务优先级,以及资源管理分配等
在开始阅读之前,我希望你能明白以下的一些基本的思想,对于理解后续的内容有一定的相关性。
- 对于非有即无的东西,为了尽量的节约空间占用,我们可以用1bit来表示信息。
- 对于程序中空间与时间的取舍,绝大部分情况下灰采用空间换取时间,毕竟时间就是金钱。
ucos-II之任务优先级
在ucos-II中,支持64个优先级,那么怎么查找最高优先级,以及优先级的设置,清除等,抛开书中讲的,你会怎么实现?
方法一:
bool Priodata[64] = {0}
,具体如何做,这个就是通过for循环来查表了,从Priodata[0]元素查询到[63],查到该元素的数字为1为止。
方法二:
- 既然都是bool型的,为什么不能用1bit来表示?何必浪费7倍的bit来表示?
所以有了如下:
/* 8*8的bit数 */
PrioTable[8] = {0};
以下是图:
思路:伪代码,应该都会看的懂(没有做其他的一些处理。)
for i in 0 to 8:
if PrioTable[i] != 0:
for j in 0 to 8:
if (PrioTable[i] & (1 << j)) == 1:
return i*8 + j
很多时候,如果能写出以上的代码,是对空间的利用更好的一点,但是,还是要经过循环(有的时候会嵌套)来达到查询的目的,是否有一种方法能有效的减少查询的次数呢?所以,这里引进一个数据,专门用来存储表示一些信息。
方法三:
- 数据的压缩,来表示整体,即增加限定词。
PS:不得不说,现实世界中处处存在这样的情况。如果要在某个小区找某一户,首先,我们会限定在那一栋,哪一个单元,哪一个楼层等等。
在这里,增加一组数据表示PrioTable[8]中当前某一个数据是否存在数据。本着节约资源的原则,我们定义一个数据:
uint8 GrpData = 0;
以下是图:
为了方便强迫症患者,把它旋转为主流的样子:
这个东西来表示什么的呢?就是用来表示PrioTable[i]中第i个元素是否有值存在
.
所以,查找最高优先级这种游戏就变成了:
- 查找GrpData数据中从bit0-bit7中最低为1的位
- 查找对应的PrioTable[i]中从bit0-bit7中最低为1的位.
PS:理解了以上这两句话的可以不用看下面的。
既然都是查找uint8中的最低为1的位,有几种方法:
- 循环查找
- 查表查找
前面一种就不用说了,说后面这种,最简单的办法就是,将uint8所能表示的数字来一个全遍历,存起来,直接索引!
所以,对于有:
0000,0000
没找到,为00000,0001
为bit0,为00000,0010
为bit1,为1.0000,0011
为bit0,为00000,0100
为bit2,为2
依次类推,这个可以通过程序生成,附带优先级查找表:
那么找到了GrpData最低位x
,与PrioTable[x]中最低位y(注意其中的x),有几种方法可以得到当前的优先级:
- x表示第几组.
- y表示第几列.
所以 x*8 + y
,如果是不喜欢用乘法的童鞋,肯定会将以上的乘法修改为x<<3 + y
到此,大体可以结束了的,有兴趣可以看看下面。
数的组合与位信息表示
很多解释上面那个x<<3的时候,解释的不是很清楚,我说说自己的理解。
在计算机或者自然科学中,都存在有效位一说,特别是计算机中,涉及到LSB,MSB等。
在对数据进行分组的时候,我们可以将数据进行拆分:
以上图为例,我们将16个数据组成为一组,当满了16个数据以后,前进一位(溢出),用高位上的数据位来表示,是不是很像16进制?数据的组合其实也是这样子的。
在就绪表中,我们将8个数据组合为1组,即通过一个uint8的后三位表示一组中的某个元素,以前面的高位来表示是第几组的数据。
所以,如果后期不是64个优先级,需要扩展或者压缩,可以通过这种分组的方式进行思考,相应的把GrpData的数据进行扩展/缩减,当然扩展的话就不能用uint8来表示了,这个需要用到循环一次的方式来表示。大体方法类似。
优先级的写入与清除
对于位操作的写入与清除,有几个很有用的位操作运算。具体的可以看我以前写的关于怎么给某一位写1与写0(即清除).(PS:貌似没找到,大概说一下:)
- 写1:
- PrioTable[i] |= (1<<j)
- 写0:
- PrioTable[i] &= (~(1<<j))
当然,还有其他的方法进行写和清除。
那么,如何做到匹配以上的思想呢?那么再创建一个MaskTable.
MaskTable[8] = {1,2,4,8,16,32,64,128};
可以直接得到的最低位索引这个表格,然后将对应的位写入进去。
资源管理表
前面说到的是查找第一个为1的数即为第一个优先级。既然查找1都有,为什么没有查找0呢?什么时候去查找0,查找0的查找表又是什么样子的?
在资源的使用上,经常会用类似的方式来标定那些资源已经被使用,那么没有被使用,如果没有被使用,肯定优先使用某一部分的资源(按照某一个可以遵循的规则)。
比如说:优先使用前面的,那是不是需要查找第一个为0的数据?
算法类似,只是256的表不同。
0. 0000,0000
bit0,为0
0000,0001
bit1,为10000,0010
bit0,为0.0000,0011
bit2,为20000,0100
bit0,为0
依次,也可通过程序生成,类似于这种图: