同优先级Ready队列
所有相同优先级的就绪任务被组织在一个链表中,调度器按照FIFO原则从这个队列中选择任务执行。
时间片轮转用于验证同优先级任务的公平调度机制。在相同优先级下,通过Tick驱动实现任务轮流执行, 确保每个任务都能公平获得CPU执行时间,避免任务饥饿。
系统运行三个同优先级任务:task_a、task_b、task_c,每个任务独立控制一个LED, 通过时间片轮转实现公平调度。验证多个同优先级任务在同一CPU上通过Round Robin机制轮流执行。
Round Robin 调度机制的核心组成
Round Robin(时间片轮转)是一种针对同优先级任务的公平调度算法。 当多个任务具有相同优先级时,系统通过时间片机制让这些任务轮流获得CPU执行权, 确保每个任务都能公平地使用CPU资源,避免某些任务长时间得不到执行。
所有相同优先级的就绪任务被组织在一个链表中,调度器按照FIFO原则从这个队列中选择任务执行。
每个任务在执行时都有一个时间片计数器,当计数器归零时,触发调度器切换到下一个任务。
系统定时器中断(Tick)周期性地递减当前任务的时间片计数器,当时间片耗尽时触发任务切换。
通过os_switch函数实现任务上下文切换,保存当前任务状态并恢复下一个任务的执行现场。
Round Robin 调度的关键特性
时间片轮转调度具有明确的调度特性,这些特性决定了同优先级任务如何公平地共享CPU资源, 以及系统如何保证每个任务都能获得执行机会。
队列组织:相同优先级任务进入同一Ready链表
选择策略:采用FIFO(先进先出)原则
队列管理:任务执行完毕后重新加入队列尾部
公平保证:每个任务都有机会被调度
固定时间片:每个任务占用固定的时间片长度
时间片单位:以系统Tick为基本单位
执行周期:任务轮流执行,形成循环
响应性:时间片越短,任务切换越频繁
触发源:系统定时器中断(Tick)
计数递减:每个Tick递减当前任务时间片
切换条件:时间片计数器归零
调度动作:触发调度器选择下一个任务
资源分配:所有任务平均获得CPU时间
避免饥饿:防止任务长时间得不到执行
适用场景:同优先级任务的公平调度
性能平衡:在公平性和切换开销间平衡
任务从创建到时间片轮转的完整执行路径
时间片轮转调度的完整实现
task_a、task_b、task_c 任务函数,分别控制不同的 LED
#include "hrtos.h"
sbit LED_A = P1^0;
sbit LED_B = P1^1;
sbit LED_C = P1^2;
void task_a(void)
{
while(1)
{
LED_A = ~LED_A;
os_task_yield();
}
}
void task_b(void)
{
while(1)
{
LED_B = ~LED_B;
os_task_yield();
}
}
void task_c(void)
{
while(1)
{
LED_C = ~LED_C;
os_task_yield();
}
}
hrtos_main 函数,创建三个同优先级任务并启动调度系统
void hrtos_main(void)
{
LED_A = LED_B = LED_C = 0;
os_task_create((unsigned int)task_a, 1, 1, 5);
os_task_create((unsigned int)task_b, 2, 1, 5);
os_task_create((unsigned int)task_c, 3, 1, 5);
}
示例执行后的预期行为
使用本示例时需要关注的关键点
三个任务使用相同的优先级(优先级 1),这是 Round Robin 调度的前提条件。 如果设置不同优先级,高优先级任务会抢占低优先级任务的执行,无法体现时间片轮转的公平性。
时间片长度影响系统的响应性和切换开销。时间片过短会导致频繁切换,增加系统开销; 时间片过长会影响任务的响应性。应根据实际应用场景合理配置时间片长度。
Round Robin 保证了同优先级任务的公平性,但不能保证实时性。 对于有严格实时性要求的任务,应使用优先级抢占调度,而非时间片轮转。
同优先级任务数量过多会影响系统性能,因为每个任务都需要在时间片内完成执行。 实际应用中应合理控制同优先级任务的数量,平衡公平性和系统效率。
深入学习的相关资源