第二部分:UCOSII操作系统任务管理机制详解----解牛之道

来源:互联网 发布:小米盒子看电视软件 编辑:程序博客网 时间:2024/05/08 08:38

任务管理原理探究:

UCOSII犹如健壮的黄牛,存活多年来,勤勤恳恳帮人们解决了很多问题,本部分一起探讨黄牛的肌肉(任务),以及肌肉之间是通过什么协调和协调机制。让我们用不严谨的的说辞来探讨这个庄严地问题。
首先让我们了解一下什么是任务?当我们在电脑面前,听着悠扬的歌声,手指敲着起伏的键盘时,电脑正在处理各种各样的任务,为我们提供方便。播放音乐,处理文字的响应后台就是各种各样的任务。电脑是一个忠实的仆人,他不能自动区分各种任务,而是有程序员来划定,而后电脑执行罢了。然而电脑又是怎么获知各个任务的信息的呢?

任务的身份证:

任务就像一个健全的人,它也有记录自身的信息的身份证,用于CPU的识别和统一管理。从抽象层次来说,人是一切社会关系的总和。同样任务也是如此,那我们就从任务本身和它之间那不太复杂的关系入手(人的关系是最复杂的)。
那咱就先拿奥巴马开刀吧(不是故意的),让我们看看任务小马马的新身份:

奥巴马的姓名,只是用于他出生用的,只是给他打上了黑人的印记;自从他出生之后,姓名(任务名)就没什么用了,而后只是专门为他设置的身份证号(优先级);除此之外,住址(栈)可是很重要的,他的重要东西都会放在家里,通过家可以找到他,并且了解到他的详细信息。有了上面的印象,咱就开始探讨一些,他的隐私:

上图展示了一个花枝招展的信息框图,你会发现:其中一些状态信息都是存在自身,但是另外的东西(堆栈、邮箱等等)却用的是指针。但是为什么这么青睐指针呢,因为指针有指向性,修改容易;例如,导弹可以击毁一个目标,你可以通过修改坐标来炸毁其他目标,就是因为导弹有着如此的杀伤力和方便性,很多国家(诸如中国,伊朗)不断研究自己的导弹。凡事都有它的两面性,万一测试导弹时,坐标输入错了,那可是出人命的!同样,指针万一指错了,那轻则程序出错,重则系统崩溃!所以,指针有其方便性,可以利用;但是,运用时一定要慎重。我们将在下面讨论任务调度是如何实现中来讨论栈的使用。

任务调度

所谓调度,就是 程序运行受到资源的限制,不得不轮流使用某一资源,如何分配任务占用资源的时间,从而引入调度概念。而这里的资源就是CPU,因为不管是多任务或分时也好在某一时间只能有一个任务使用CPU,所以CPU就是重要的共享资源,也是当今的一个瓶颈(为了解决这个瓶颈引入了多核处理器等等)。
如上图所示:操作系统在CPU和任务之间加了一个调度,来处理任务和CPU关系;Any problem in computer science can be solved by another layer of indirection.计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。而此处的中间层无非时一个所谓的调度层,其组成就是一个调调算法,也不是那么复杂。调度的作用就是选择适当的任务,让它使用CPU。在UCOSII中任务和它的优先级有生死关系,一一对应,也就是选择最高优先级的任务让其运行。
如何选择最高优先级的任务呢?想到的方法就是查找,为了查找我们学过了很多方法,最常用的的是在链表中查找;然而在链表中查找,首先要维系一个链表,由于在UCOSII中任务切换非常频繁,而维系一个链表,就需要遍历链表,插入,删除等等,这将消耗很长宝贵的时间(注意咱这可是实时操作系统哦),所以直接就将这个方法排除掉了。我们来看看到底UCOSII的教父是如何实现的。
引入了一个矩阵,类似一个标志矩阵:由于UCOSII最多可以切换64个任务,所以就引入了8*8的矩阵,每个任务在这个矩阵中有特定的位置,而这个位置有它的优先级决定,即,优先级越高排的越靠前。这个矩阵就是我们所说的就绪表。顾名思义,就绪表里存的都是已经准备好运行的任务(即就绪的任务),根据就绪任务的优先级,将表中相应位置位,同理若要将任务从就绪表中删除,直接将相应位置0就好了。
就续表引入之后,我们不能走逐步检索的老路,那么如何使用呢?既然为了提高切换速率,必然有所损失,采用空间换时间的策略。
CPU每次通过就续表选择任务的时候,总是将最高优先级的任务;既然这样,我们设计算法将最高优先级选择出来便可。矩阵有两个维度-----行和列,就可以确定位置。而在就续表中确定位置就确定了优先级,所以优先级和行列产生了紧密的联系。
从而行和列各自形成一个数组:由于BYTE型就刚好含有八位,所以每一行(列)可以定义为BYTE型。定义每一行BYTE为OSRdyTbl总共八行所以定义OSRdyTbl[8];列所对应BYTE为OSRdyGrp,列中相应位置位表示对应行中有待运行任务。

1、在就续表中置位相应表格操作过程图解:


2、就续表中响应位清零过程图解:

注意列信息OSRdyGrp是一行共有的:图示:
清零过程无非就是将OSRdyGrp和相应行的OSRdyTbl清零,将它们和只有相应位为零,其它位都是1的数(何以由上面掩码表取反获得)进行与操作,但要注意的是OSRdyGrp是否清零必须看OSRdyTbl是否为零。

3、查找最高优先级任务过程图解:


下面的问题是如何根据优先级获得任务指针?由于在创建新任务时,已经将所创建的任务指针,以优先级为下标更新到指针数组OSTCBPrioTbl[64],所以得到优先级后直接使用该指针数组就可得到最高优先级任务的指针,得以恢复任务信息。

任务切换底层实现原理:

上面C语言部分介绍完毕,而后讨论一下底层(汇编层面)是如何实现的:
任务切换最重要的就是栈之间的顺利切换交接,因为栈内储存着关系到任务生死存亡的信息。

至此,我们将任务相关原理介绍完毕,以后我们会分析源代码。

1 0