1. 最早截止时间优先EDF(Earliest DeadlineFirst)算法是非常著名的实时调度算法之一。在每一个新的就绪状态,调度器都是从那些已就绪但还没有完全处理完毕的任务中选择最早截止时间的任务,并将执行该任务所需的资源分配给它。在有新任务到来时,调度器必须立即计算EDF,排出新的定序,即正在运行的任务被剥夺,并且按照新任务的截止时间决定是否调度该新任务。如果新任务的最后期限早于被中断的当前任务,就立即处理新任务。按照EDF算法,被中断任务的处理将在稍后继续进行。
2. 该算法的思想是从两个任务中选择截至时间最早的任务,把它暂作为当前处理任务,再判断该任务是否在当前周期内,若不在当前周期内,就让另一任务暂作当前处理任务,若该任务也不在当前周期内,就让CPU空跑到最靠近的下一个截至时间的开始,若有任务在该周期内,就判断该任务的剩余时间是否小于当前截至时间与当前时间的差,若小于,则让该任务运行到结束.否则,就让该任务运行到该周期的截止时间,就立即抢回处理器,再判断紧接着的最早截至时间,并把处理器给它,做法同上,如此反复执行.
2. 该算法的思想是从两个任务中选择截至时间最早的任务,把它暂作为当前处理任务,再判断该任务是否在当前周期内,若不在当前周期内,就让另一任务暂作当前处理任务,若该任务也不在当前周期内,就让CPU空跑到最靠近的下一个截至时间的开始,若有任务在该周期内,就判断该任务的剩余时间是否小于当前截至时间与当前时间的差,若小于,则让该任务运行到结束.否则,就让该任务运行到该周期的截止时间,就立即抢回处理器,再判断紧接着的最早截至时间,并把处理器给它,做法同上,如此反复执行.
3.最早截止时间优先即EDF算法的程序如下:
#include<stdio.h>
#define closetime 200
#define PERIOD1 10 /*任务1的周期*/
#define PERIOD2 40 /*任务2的周期*/
#define CPUTIME1 5 /*任务1需要的CPU时间*/
#define CPUTIME2 20 /*任务2需要的CPU时间*/
typedef struct TCB { int period; /*周期*/
int cputime;/*需要的cpu时间*/
int remain; /*剩余的cpu时间*/
int pnum; /*所处周期数*/
int laxity; /*松弛度*/
} TCB;
TCB tcb[2]; /*任务控制块,容易扩充为多个*/
int curtime; /*当前时间,初始为0*/
void init(void)
{
int i;float f;
curtime=0;/*当前时间为0*/
tcb[0].period=PERIOD1;tcb[0].cputime=CPUTIME1;/*周期与*/
tcb[1].period=PERIOD2;tcb[1].cputime=CPUTIME2;/*CPU时间*/
f=(float)tcb[0].cputime/tcb[0].period+(float)tcb[1].cputime/tcb[1].period;/*数据合法性检查*/
if(f>1)
{
printf("非法周期!");return;
}
for(i=0;i<2;++i){ tcb[i].pnum=1;/*初始周期号*/
tcb[i].remain=tcb[i].cputime;/*初始剩余时间*/
}
}
void schedule(void)/*调度程序*/
{
int i,p;/*i是被调度运行任务,p是当前周期值*/
int duration;/*本次运行持续时间*/
i=tcb[0].period*tcb[0].pnum<=tcb[1].period*tcb[1].pnum?0:1;/*选最早截止时间的的任务*/
if(curtime<tcb[i].period*(tcb[i].pnum-1))/*尚未进入该周期*/
{
p=tcb[i].period*(tcb[i].pnum-1);
i=(i+1)%2;/*选另一个任务*/
if(curtime<tcb[i].period*(tcb[i].pnum-1))/*尚未进入该周期*/
curtime=p;
else if(tcb[i].remain<=p-curtime)
duration=tcb[i].remain; /*让它运行到结束*/
else
duration=p-curtime;/*只能运行到下个周期到来时刻*/
tcb[i].remain-=duration;/*修改剩余时间*/
printf("任务号=%-3d周期序号=%-3d调度时刻=%-6d运行时间长度=%-3d\n",i,tcb[i].pnum,curtime,duration);
curtime+=duration;/*时间推进到下一调度时刻*/
if(tcb[i].remain==0)
{/*本周期的任务已完成*/
tcb[i].pnum++;/*向前推进一个周期*/
tcb[i].remain=tcb[i].cputime;/*设置初始剩余时间*/
}
}
else
{
p=tcb[i].period*tcb[i].pnum;
if(tcb[i].remain<=p-curtime)
duration=tcb[i].remain; /*让它运行到结束*/
else
duration=p-curtime;/*只能运行到下个周期到来时刻*/
tcb[i].remain-=duration;/*修改剩余时间*/
printf("任务号=%-3d周期序号=%-3d调度时刻=%-6d运行时间长度=%-3d\n",i,tcb[i].pnum,curtime,duration);
curtime+=duration;/*时间推进到下一调度时刻*/
if(tcb[i].remain==0)
{/*本周期的任务已完成*/
tcb[i].pnum++;/*向前推进一个周期*/
tcb[i].remain=tcb[i].cputime;/*设置初始剩余时间*/
}
}
}
void main(void)
{
init();
while(curtime<closetime)
schedule();
}