VxWorks中的任务及调度(五):VxWorks任务调度机制

时间:2024-11-12 16:06:53


第四节: VxWorks任务调度机制

在操作系统中,任务调度存在两种方式:基于优先级调度和基于时间片调度。嵌入式系统中任务调度一般都是基于优先级的调度方式,VxWorks也就是传说中的抢占式调度。有没有方法可以关闭这种抢占式调度呢?VxWorks操作系统定义了一个全局变量roundRobinOn用于表示时间片轮转使能,系统默认该值为FALSE,即VxWorks默认是基于优先级的任务调度,也就是说当高优先级任务readyCPU将交给高优先级任务。(见源码, kernelInit())当低优先级任务被高优先级任务抢占后,会发生什么呢?当系统中存在多个优先级相同的任务ready时,此时任务如何调度呢?

有一种说法是:操作系统可以选择在相同优先级的任务间采用时间片轮转的方式,即如果任务A、任务B、任务C优先级都为80,那么A运行时间t后由任务B运行,再过时间t后任务C运行。虽然这是一种明确的调度算法,但是阅读代码和观察系统运行未发现此种方式的有效支撑,至少在FH的系统中并没有使用这种方式。众所周知,只有为ready状态的任务才可能获取cpu进入运行状态,尽管认为处于pend状态的最高优先级任务获取所需资源后直接进入running状态,但个人认为到不如理解为处于pend状态的任务获取资源进入ready状态,因为优先级最高再进入running状态。

VxWorks系统内部维护一个ready队列,优先级高的任务排在队列前面,相同优先级的任务按照进入队列的先后顺序排列。低优先级任务被高优先级任务抢占后,任务运行信息保存进TCB中,但该任务在ready队列中的顺序不变,也就是说被抢占的任务排在同优先级任务的最前面。

有什么方法可以阻止CPU被高优先级任务抢占么?taskLock()可以暂时关闭的优先级抢占调度机制。但taskLock()只能关闭调度任务,不能关闭中断。

未发生优先级抢占时任务何时会放弃CPU的使用权呢?资源!系统资源!正在运行的任务一旦缺乏某种系统资源时,便会切换出运行状态!如果缺乏CPU,会进入ready状态,缺乏其他资源时,便会进入pend状态。除了CPU,还有哪些属于系统资源?主要是I/O、信号量、消息队列和内存空间等。

这里有一个问题:如果有两个任务:任务A优先级为10,任务B优先级为80,任务A阻塞于消息队列gMsg1(msgQReceive(gMsg1))gMsg1在任务B中发生(msgQSend(gMsg1)), 如果CPU被位于中间优先级的任务抢占,Task B始终不能得到CPU控制权,那么Task A是否将永久阻塞呢?

为避免这种情况,VxWorks 引进优先级继承机制。 为使用优先级继承机制,当使用互斥信号量时,VxWorks 提供了一个附加的选项 SEM_INVERSION_SAFE,它允许使用优先级继承算法,该算法保证占有一个资源的任务,在其运行时,其优先级等于阻塞在该资源上的所有任务的优先级的最高值。当执行完成,这个任务释放资源,返回正常的优先级。因此,这个继承了最高优先级的任务, 将不会被优先级比它的正常优先级高但又比继承的优先级低的任务抢占。

在本例中,当Task A阻塞于gMsg1时,Task B则继承Task A的优先级为10直到Task B 执行完msgQSend.