就绪表

就绪表

  • 适用于理解ucosII任务优先级,以及资源管理分配等

在开始阅读之前,我希望你能明白以下的一些基本的思想,对于理解后续的内容有一定的相关性。

  1. 对于非有即无的东西,为了尽量的节约空间占用,我们可以用1bit来表示信息。
  2. 对于程序中空间与时间的取舍,绝大部分情况下灰采用空间换取时间,毕竟时间就是金钱。

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个元素是否有值存在.

所以,查找最高优先级这种游戏就变成了:

  1. 查找GrpData数据中从bit0-bit7中最低为1的位
  2. 查找对应的PrioTable[i]中从bit0-bit7中最低为1的位.

PS:理解了以上这两句话的可以不用看下面的。

既然都是查找uint8中的最低为1的位,有几种方法:

  1. 循环查找
  2. 查表查找

前面一种就不用说了,说后面这种,最简单的办法就是,将uint8所能表示的数字来一个全遍历,存起来,直接索引!
所以,对于有:

  1. 0000,0000没找到,为0
  2. 0000,0001为bit0,为0
  3. 0000,0010为bit1,为1.
  4. 0000,0011为bit0,为0
  5. 0000,0100为bit2,为2

依次类推,这个可以通过程序生成,附带优先级查找表:

那么找到了GrpData最低位x,与PrioTable[x]中最低位y(注意其中的x),有几种方法可以得到当前的优先级:

  1. x表示第几组.
  2. 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,0000bit0,为0

  1. 0000,0001bit1,为1
  2. 0000,0010bit0,为0.
  3. 0000,0011bit2,为2
  4. 0000,0100bit0,为0
    依次,也可通过程序生成,类似于这种图:
原文地址:https://www.cnblogs.com/ply616/p/5713246.html