最低松弛度优先(LLF)算法是根据任务紧急(或松弛)的程度,来确定任务的优先级。任务的紧急程度愈高,为该任务所赋予的优先级就愈高,使之优先执行。在实现该算法时要求系统中有一个按松弛度排序的实时任务就绪队列,松弛度最低的任务排在队列最前面,被优先调度。松弛度的计算方法如下:
任务的松弛度=必须完成的时间-其本身的运行时间-当前时间
其中其本身运行的时间指任务运行结束还需多少时间,如果任务已经运行了一部分,则:
任务松弛度=任务的处理时间-任务已经运行的时间 – 当前时间
几个注意点:
1. 该算法主要用于可抢占调度方式中,当一任务的最低松弛度减为0时,它必须立即抢占CPU,以保证按截止时间的要求完成任务。
2. 计算关键时间点的各进程周期的松弛度,当进程在当前周期截止时间前完成了任务,则在该进程进入下个周期前,无需计算它的松弛度。
3. 当出现多个进程松弛度相同且为最小时,按照“最近最久未调度”的原则进行进程调度。
1、结构体描述进程
定义及其意义如下:
typedef struct process //进程
{
char pname[5]; //进程名
int deadtime; //周期
int servetime; //执行时间
//周期进程某一次执行到停止的剩余需执行时间(考虑到抢占),初始为deadtime
int lefttime;
int cycle; //执行到的周期数
//进程最近一次的最迟开始执行时间,- currenttime 即为松弛度
int latestarttime;
//进程下一次最早开始时间
int arivetime;
intk; //k=1,表示进程正在运行,否则为0,表示进程不在执行期间
/*
若存在最小松弛度进程个数多于1个,
则采用最近最久未使用算法
采用一计数器LRU_t
*/
intLRU_t;
}process;
2、循环队列存储进程
定义及其意义如下:
typedef struct sqqueue //循环队列
{
process *data[queuesize];
int front,rear;
} sqqueue;
重难点分析
1、实时系统可调度条件
当实时系统中有M个硬实时任务,它们的处理时间可表示为Ci ,周期时间表示为Pi,则在采用N个处理机的系统中,必须满足限制条件:
Σ<=N
系统才是可调度的。现在单处理机下,即Σ<=1,否则认为不满足实时系统调度条件。
2、进程的结构体描述
typedefstruct process //进程
{
char pname[5];
int deadtime;
int servetime;
int lefttime;
int cycle;
int latestarttime;
int arivetime;
intk;
intLRU_t;
}process;
进程首先包括进程名pname、周期时间deadtime、执行时间servetime;
为控制周期进程的执行周期数,应有一个进程计数cycle,初始化为1;
因为是实时系统中的进程,该有一个进程执行最早开始时间arivetime和最晚开始时间latestarttime;
考虑到进程抢占,所以有一个进程某一次执行中断后的剩余执行时间,需用于计算松弛度。
还可以有一个进程运行状态位k,1即表示正在运行,0则表示没有运行。
当出现多个进程松弛度相同且为最小时,按照“最近最久未调度”的原则进行进程调度。所以有一个计数器LRU_t计算每一个进程在调度时,调度与被调度的情况。初始均为0,调度某一进程时,则该进程以外的其他进程均要在计数器上加1。松弛度相同时,选择计数器LRU_t值最大的。
补充说明:最开始时,我们没有考虑进程运行状态位k,后来是为了输出进程的执行开始和结束时间而加的,可以根据进程的运行状态位,进行输出进程的执行时间段。
对于出现多个进程松弛度相同且为最小时,最开始选择的是每次都采用最接近队尾的进程,这样虽然满足对于题目所给的实例,但是实际上是还是不符要求的,最后选择最近最久未使用算法的思想得以解决。
3、循环队列的属性及遍历
队列中的进程以数组的形式进程存储;
队列的队首为front,队尾为rear,遍历时要考虑队空否,或者输入进程时,要考虑进程是否填满了队列。
循环队列,队空为:front == rear
队满为:(rear+1)%queuesize == front
4、松弛度的计算
松弛度 = 任务必须完成的时间 — 任务本身的运行时间 — 当前时间;
即松弛度 = 周期*需执行的次数 —(上一次)执行的剩余时间 —当前时间
即松弛度= deadtime× cycle — lefttime — currenttime
而(可能被中断过)进程最迟开始执行时间arivetime = deadtime× cycle —lefttime
所以arivetime— currenttime <=0 ,即为松弛度为0,抢占当前正在运行进程。
5、最小松弛度的进程
采用遍历队列中当前时间下可以开始运行的进程,即最早开始时间arivetime=deadtime*( cycle-1) 小于当前时间,比较各进程松弛度,得出最小松弛度的进程。
6、进程的抢占
由上可知进程的松弛度的计算方法,依旧采用遍历队列的方式,循环寻找松弛度为0 的进程:如果存在就让其跳出循环,返回该进程;否则,队首指针向下,直至队尾,如果遍历完都不存在松弛度为0的进程,则返回当前进程即可。但未考虑松弛度同时为0的进程存在多个的情况。
7、时钟
由于是实时系统,我们采用时钟计时法。即在每1ms的时间变化时,都要进行LLF进程的选择。即在当前时间currenttime下,currenttime初始为0,循环++,直至到达执行总时间MAXTIME。
8、最低松弛度相同的若干进程调度
对于出现多个进程松弛度相同且为最小时,选择的原则是,刚刚执行过的进程,此时应不再执行,让给其他具有同样最低松弛度的进程。
最开始选择的是每次都采用最接近队尾的进程。在遍历的过程中,将当前队列赋给一临时队列,对临时队列进行遍历,所以并不改变原队列的队首队尾指针。在每次选择最低松弛度的进程时,我们都是选择离队尾最近的进程,但这样存在着问题,例如:A:50ms(周期),10(执行时间),B:20ms(周期),10(执行时间),C:50ms(周期),15(执行时间),在第80ms时还是在执行完B4后,执行B5,而非A2。
这样虽然满足对于题目所给的实例,但是实际上是还是不符要求的。最后选择最近最久未使用(LRU)算法的思想得以解决。即给每一个进程设置一个计数器。
9、currenttime 在边界值时的情况
在currenttime == MAXTIME时,可能存在进程正好要开始执行,例如题目所给的例子:100ms时,A进程要开始执行,但是我们不应让其开始执行,所以应该临界处理;
同理,可能也存在进程正在执行当中,此时应该输出该进程在没有完成其周期执行时间的下的运行时间段。
10、当前时间没有进程运行的情况
假若只有一个进程,周期时间是20ms,执行时间是10ms,那么在10—20ms、30—40ms、50—60ms……时,是没有进程运行的情况,即此时最低松弛度的进程为空。
//最低松弛度调度算法LLF
//正确的。。。
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define queuesize 10
#define MAXTIME 150 //考虑前100ms时间
#define MINLLF 9999
#define PRO_LRU_T 0
//进程结构体
typedef struct process //进程
{
char pname[5]; //进程名
int deadtime; //周期
int servetime; //执行时间
//周期进程某一次执行到停止的剩余需执行时间(考虑到抢占),初始为deadtime
int lefttime;
int cycle; //执行到的周期数
//进程最近一次的最迟开始执行时间,- currenttime 即为松弛度
int latestarttime;
//进程下一次最早开始时间
int arivetime;
int k; //k=1,表示进程正在运行,否则为0,表示进程不在执行期间
/*
若存在最小松弛度进程个数多于1个,
则采用最近最久未使用算法
采用一计数器LRU_t
*/
int LRU_t;
}process;
typedef struct sqqueue //循环队列
{
process *data[queuesize];
int front,rear;
} sqqueue;
//初始化n个进程
void Initprocess(process *pro,int n)
{
int i;
process *p=pro;
for(i=0;i<n;i++)
{
*(p->pname)='\0';
p->deadtime=0;
p->servetime=0;
p->lefttime=0;
p->cycle=0;
p->latestarttime=0;
p->arivetime=0;
p->k=0;
p->LRU_t=0;
p++;
}
}
//初始化队列(队空)
void InitQueue(sqqueue *que)
{
que->front=que->rear=0;
}
//进程进入循环队列
void enterQueue(sqqueue *que,process *pro)
{
//判断循环队列是否已满
if( (que->rear+1)%queuesize == que->front )
printf("队列已满!\n");
else
{
que->data[que->rear] = pro; //进程放入队尾
que->rear = (que->rear+1)%queuesize; //队尾指针加1
printf("%s成功入队!\n",pro->pname); //显示进程入队
}
}
//从当前队列中找到最低松弛度的进程
process *llf(sqqueue *dui, int currenttime)
{
sqqueue *q1 = dui;
process *currentpro, *pro;
int minllf = MINLLF , llf;
int pro_LRU_t = PRO_LRU_T;
int front = q1->front, rear=q1->rear; //队首元素??
//将队首进程赋给当前进程
currentpro = q1->data[front];
if( currenttime <= MAXTIME )
{
//求最短松弛度currentpro,如果队列中只有一个进程
if( front==rear )
{
return currentpro;
printf("%dms时%s%d进程的松弛度为:%d\n",currenttime,currentpro->pname,currentpro->cycle,llf);
}
//进程数目多于一个
else
{
/*
找当前时间下可以开始执行的进程中松弛度最小的,
赋给currentpro.
当最小松弛度的进程多于1个,
我们采用的是最后1个最小松弛度进程?
*/
do
{
if(front!=rear )
{
pro=q1->data[front];
if(pro->arivetime <= currenttime && currenttime<= MAXTIME)
{
//计算松弛度 = 周期*需执行的次数- (上一次)执行的时间 -当前时间
llf=(pro->deadtime)*(pro->cycle)- pro->lefttime - currenttime;
printf("%dms时%s%d进程的松弛度为:%d\n",currenttime,pro->pname,pro->cycle,llf);
if(minllf>=llf) //比较得出最低松弛度
{
if( pro->LRU_t >= pro_LRU_t )
{
pro_LRU_t = pro->LRU_t ;
minllf=llf;
currentpro=pro;
}
}
}
front=(front+1)%queuesize;
}
else
break;
}while(front!=rear ); //检测队列是否遍历完
}
}
return currentpro;
}
//寻找松弛度 <=0 的抢占进程,替代当前最小松弛度进程
process *leastlaxityfirst(sqqueue *dui,int currenttime)
{
sqqueue *q1=dui;
process *pro=NULL, *nextpro;
int front= q1->front, rear= q1->rear ;
/*
当队列不空,寻找当前时刻
是否有松弛度为0(需抢占进程)的进程
*/
while(front!=rear)
{
nextpro=q1->data[front];
/*
pro->latestarttime初始为:
(pro->deadtime)*(pro->cycle) - pro->servetime;
pro->latestarttime - currenttime 即为松弛度
pro->latestarttime - currenttime <= 0 ,
即松弛度 = 0,抢占,跳出循环
*/
if( nextpro->latestarttime <= currenttime )
break;
else
front=(front+1)%queuesize;
}
//如果队列空,返回pro
if(front==rear)
return pro;
//队列不空,nextpro为此时抢占正在执行的进程的进程
else
return nextpro;
}
//从队列中读取进程的过程
void LLF_Process( sqqueue *dui )
{
int currenttime=0;
sqqueue *que=dui;
int front = que->front;
int rear = que->rear;
process *currentpro,*pro, *tmppro;
//currentpro为当前时间队列中松弛度最低的进程
currentpro=llf(que, currenttime);
//在MAXTIME时间内考虑
while(currenttime <= MAXTIME)
{
/*
最低松弛度进程为空,
即为当前时间没有可运行的进程
*/
if(currentpro==NULL)
{
printf("%dms时无可运行进程!\n",currenttime);
break;
}
else
{
if((currentpro->arivetime <= currenttime ) )
{
if(currenttime==MAXTIME)
{
//当进程正在运行
if(currentpro->k == 1)
printf("%d ms: %s%d\n\n",currenttime,currentpro->pname,currentpro->cycle);
//当此时没有进程运行
else
printf("\n=======执行只考虑前%dms,现时间已到%dms了!======\n",currenttime,currenttime);
break;
}
else if (currenttime!=MAXTIME)
{
if( currentpro->k== 0 )
{
printf("=> %dms时刻%s%d进程开始执行: %d - ",currenttime,currentpro->pname,currentpro->cycle,currenttime);
currentpro->k = 1; //表明进程开始运行
do
{
if(front!=rear )
{
pro=que->data[front];
if(pro != currentpro )
pro->LRU_t++;
front=(front+1)%queuesize;
}
else
break;
}while(front!=rear );
}
currenttime++; //当前时间增加
currentpro->lefttime--; //运行剩余时间减少
//当剩余运行时间等于0, 即当程序运行结束
if(currentpro->lefttime == 0)
{
if(currentpro->k==1)
{
printf("%d ms: %s%d\n\n",currenttime,currentpro->pname,currentpro->cycle);
currentpro->k=0; //表明进程开始进入不执行状态
}
currentpro->cycle++;
currentpro->lefttime=currentpro->servetime;
currentpro->arivetime=(currentpro->deadtime)*(currentpro->cycle-1);
currentpro->latestarttime=(currentpro->deadtime)*(currentpro->cycle)-(currentpro->servetime);
currentpro=llf(que,currenttime);
}
//当进程未运行完毕。。。(可能被抢占)
else
{
//pro为抢占当前正执行进程的进程
pro = leastlaxityfirst(que,currenttime);
if( pro!= NULL )
{
/*
如果当前存在抢占进程,
即pro != currentpro,
则使currentpro进程进入不执行状态
*/
if(pro != currentpro)
{
if( currentpro->k == 1 )
currentpro->k = 0;
printf("%d ms: %s%d\n\n",currenttime,currentpro->pname,currentpro->cycle);
printf("%dms时%s%d进程被进程%s%d进程抢占!\n",currenttime,currentpro->pname,currentpro->cycle,pro->pname,pro->cycle);
}
/*
使currentpro为松弛度最小的进程,
不论是否是抢占程序。
*/
currentpro = pro;
}
}
}
}
//当进程下一次开始时间还没到
else if( currentpro->arivetime >= currenttime )
{
if(currenttime==MAXTIME)
{
printf("\n=======执行只考虑前%dms,现时间已到%dms了!======\n",currenttime,currenttime);
break;
}
else
{
printf("第%dms时没有进程到达!\n");
currenttime++;
currentpro=llf(que,currenttime);
}
}
}
}
}
int main()
{
sqqueue *dui,*dui2;
process *pro,pro2[queuesize],*pro3;
int front,rear,ci=0,pi=0;
int flag=1,i;
char ch,ch2,name[5];
printf("\n*******最低松弛调度**********\n\n");
dui=(sqqueue *)malloc(sizeof(sqqueue));
dui->rear = dui->front = 0;
dui2=(sqqueue *)malloc(sizeof(sqqueue));
dui2->rear=dui2->front=0;
while(1)
{
i=0;
InitQueue(dui) ;
Initprocess(pro2,queuesize);
printf("请输入周期进程有关的信息:\n");
while(flag)
{
pro=pro2+i;
printf("\n请输入进程名(长度小于5):");
gets(name);
strcpy(pro->pname,name);
printf("\n请输入进程的周期:");
scanf("%d",&(pro->deadtime));
getchar();
printf("\n请输入进程的执行时间:");
scanf("%d",&(pro->servetime)); getchar();
pro->lefttime = pro->servetime; //
pro->cycle=1; //初始时进程从第一周期开始执行
pro->latestarttime=(pro->deadtime)*(pro->cycle) - pro->servetime; //进程下一次最迟开始执行的时间
pro->arivetime=(pro->deadtime)*(pro->cycle-1); // 进程下一次开始的最早时间
pro->k = 0;
enterQueue(dui,pro); //进队列
i++; //进程个数
printf("\n是否继续进程信息的输入(0:结束,1:继续):");
scanf("%d",&flag); getchar();
}
dui2=dui;
front=dui2->front;
rear=dui2->rear;
while(front!=rear)
{
pro3=dui2->data[front];
ci=pro3->servetime+ci; //各进程执行的时间总和
pi=pro3->deadtime+pi; //各周期总和
front=(front+1)%queuesize;
}
//根据实时系统的要求:(ci/pi)<=1
if((ci/pi)<=1)
{
LLF_Process(dui);
printf("\n**********进程运行完毕!************\n");
printf("\n");
printf("是否要结束使用(Y/N)?");
scanf("%c",&ch); getchar();
if ('Y'== toupper(ch))
{
printf("\n 任意键结束! ");
scanf("%c",&ch2);
exit(0);
}
else
flag=1;
}
else
{
printf("所输入的进程不满足要求! ");
printf("\n是否重新输入(Y/N):\n");
scanf("%c",&ch); getchar();
if ('N'==toupper(ch))
{
printf("请按任意键结束\n");
exit(0);
}
}
}
return 0;
}
1、不存在抢占,但存在最低松弛度相同的进程的选择
*******最低松弛调度**********
请输入周期进程有关的信息:
请输入进程名(长度小于5):A
请输入进程的周期:20
请输入进程的执行时间:10
A成功入队!
是否继续进程信息的输入(0:结束,1:继续):1
请输入进程名(长度小于5):B
请输入进程的周期:50
请输入进程的执行时间:10
B成功入队!
是否继续进程信息的输入(0:结束,1:继续):1
请输入进程名(长度小于5):C
请输入进程的周期:50
请输入进程的执行时间:15
C成功入队!
是否继续进程信息的输入(0:结束,1:继续):0
0ms时A1进程的松弛度为:10
0ms时B1进程的松弛度为:40
0ms时C1进程的松弛度为:35
=> 0ms时刻A1进程开始执行: 0 - 10 ms: A1
10ms时B1进程的松弛度为:30
10ms时C1进程的松弛度为:25
=> 10ms时刻C1进程开始执行: 10 - 25 ms: C1
25ms时A2进程的松弛度为:5
25ms时B1进程的松弛度为:15
=> 25ms时刻A2进程开始执行: 25 - 35 ms: A2
35ms时B1进程的松弛度为:5
=> 35ms时刻B1进程开始执行: 35 - 45 ms: B1
45ms时A3进程的松弛度为:5
=> 45ms时刻A3进程开始执行: 45 - 55 ms: A3
55ms时B2进程的松弛度为:35
55ms时C2进程的松弛度为:30
=> 55ms时刻C2进程开始执行: 55 - 70 ms: C2
70ms时A4进程的松弛度为:0
70ms时B2进程的松弛度为:20
=> 70ms时刻A4进程开始执行: 70 - 80 ms: A4
80ms时A5进程的松弛度为:10
80ms时B2进程的松弛度为:10
=> 80ms时刻B2进程开始执行: 80 - 90 ms: B2
90ms时A5进程的松弛度为:0
=> 90ms时刻A5进程开始执行: 90 - 100 ms: A5
100ms时A6进程的松弛度为:10
100ms时B3进程的松弛度为:40
100ms时C3进程的松弛度为:35
=======执行只考虑前100ms,现时间已到100ms了!======
**********进程运行完毕!************
是否要结束使用(Y/N)?
2、存在抢占的情况
*******最低松弛调度**********
请输入周期进程有关的信息:
请输入进程名(长度小于5):A
请输入进程的周期:20
请输入进程的执行时间:10
A成功入队!
是否继续进程信息的输入(0:结束,1:继续):1
请输入进程名(长度小于5):B
请输入进程的周期:50
请输入进程的执行时间:25
B成功入队!
是否继续进程信息的输入(0:结束,1:继续):0
0ms时A1进程的松弛度为:10
0ms时B1进程的松弛度为:25
=> 0ms时刻A1进程开始执行: 0 - 10 ms: A1
10ms时B1进程的松弛度为:15
=> 10ms时刻B1进程开始执行: 10 - 30 ms: B1
30ms时B1进程被进程A2进程抢占!
=> 30ms时刻A2进程开始执行: 30 - 40 ms: A2
40ms时A3进程的松弛度为:10
40ms时B1进程的松弛度为:5
=> 40ms时刻B1进程开始执行: 40 - 45 ms: B1
45ms时A3进程的松弛度为:5
=> 45ms时刻A3进程开始执行: 45 - 55 ms: A3
55ms时B2进程的松弛度为:20
=> 55ms时刻B2进程开始执行: 55 - 70 ms: B2
70ms时B2进程被进程A4进程抢占!
=> 70ms时刻A4进程开始执行: 70 - 80 ms: A4
80ms时A5进程的松弛度为:10
80ms时B2进程的松弛度为:10
=> 80ms时刻B2进程开始执行: 80 - 90 ms: B2
90ms时A5进程的松弛度为:0
=> 90ms时刻A5进程开始执行: 90 - 100 ms: A5
100ms时A6进程的松弛度为:10
100ms时B3进程的松弛度为:25
=======执行只考虑前100ms,现时间已到100ms了!======
**********进程运行完毕!************
是否要结束使用(Y/N)?
3、在截止时间时,某一进程还没有运行完
*******最低松弛调度**********
请输入周期进程有关的信息:
请输入进程名(长度小于5):A
请输入进程的周期:20
请输入进程的执行时间:10
A成功入队!
是否继续进程信息的输入(0:结束,1:继续):1
请输入进程名(长度小于5):B
请输入进程的周期:50
请输入进程的执行时间:10
B成功入队!
是否继续进程信息的输入(0:结束,1:继续):1
请输入进程名(长度小于5):C
请输入进程的周期:50
请输入进程的执行时间:15
C成功入队!
是否继续进程信息的输入(0:结束,1:继续):0
0ms时A1进程的松弛度为:10
0ms时B1进程的松弛度为:40
0ms时C1进程的松弛度为:35
=> 0ms时刻A1进程开始执行: 0 - 10 ms: A1
10ms时B1进程的松弛度为:30
10ms时C1进程的松弛度为:25
=> 10ms时刻C1进程开始执行: 10 - 25 ms: C1
25ms时A2进程的松弛度为:5
25ms时B1进程的松弛度为:15
=> 25ms时刻A2进程开始执行: 25 - 35 ms: A2
35ms时B1进程的松弛度为:5
=> 35ms时刻B1进程开始执行: 35 - 45 ms: B1
45ms时A3进程的松弛度为:5
=> 45ms时刻A3进程开始执行: 45 - 55 ms: A3
55ms时B2进程的松弛度为:35
55ms时C2进程的松弛度为:30
=> 55ms时刻C2进程开始执行: 55 - 70 ms: C2
70ms时A4进程的松弛度为:0
70ms时B2进程的松弛度为:20
=> 70ms时刻A4进程开始执行: 70 - 80 ms: A4
80ms时A5进程的松弛度为:10
80ms时B2进程的松弛度为:10
=> 80ms时刻B2进程开始执行: 80 - 90 ms: B2
90ms时A5进程的松弛度为:0
=> 90ms时刻A5进程开始执行: 90 - 100 ms: A5
100ms时A6进程的松弛度为:10
100ms时B3进程的松弛度为:40
100ms时C3进程的松弛度为:35
=> 100ms时刻A6进程开始执行: 100 - 110 ms: A6
110ms时B3进程的松弛度为:30
110ms时C3进程的松弛度为:25
=> 110ms时刻C3进程开始执行: 110 - 125 ms: C3
125ms时A7进程的松弛度为:5
125ms时B3进程的松弛度为:15
=> 125ms时刻A7进程开始执行: 125 - 135 ms: A7
135ms时B3进程的松弛度为:5
=> 135ms时刻B3进程开始执行: 135 - 145 ms: B3
145ms时A8进程的松弛度为:5
=> 145ms时刻A8进程开始执行: 145 - 150 ms: A8
=======执行只考虑前150ms,现时间已到150ms了!======
**********进程运行完毕!************
是否要结束使用(Y/N)?
4、存在某一时刻没有进程运行
*******最低松弛调度**********
请输入周期进程有关的信息:
请输入进程名(长度小于5):A
请输入进程的周期:20
请输入进程的执行时间:10
A成功入队!
是否继续进程信息的输入(0:结束,1:继续):0
0ms时A1进程的松弛度为:10
=> 0ms时刻A1进程开始执行: 0 - 10 ms: A1
第10ms时没有进程到达!
第11ms时没有进程到达!
第12ms时没有进程到达!
第13ms时没有进程到达!
第14ms时没有进程到达!
第15ms时没有进程到达!
第16ms时没有进程到达!
第17ms时没有进程到达!
第18ms时没有进程到达!
第19ms时没有进程到达!
20ms时A2进程的松弛度为:10
=> 20ms时刻A2进程开始执行: 20 - 30 ms: A2
第30ms时没有进程到达!
第31ms时没有进程到达!
第32ms时没有进程到达!
第33ms时没有进程到达!
第34ms时没有进程到达!
第35ms时没有进程到达!
第36ms时没有进程到达!
第37ms时没有进程到达!
第38ms时没有进程到达!
第39ms时没有进程到达!
40ms时A3进程的松弛度为:10
=> 40ms时刻A3进程开始执行: 40 - 50 ms: A3
第50ms时没有进程到达!
第51ms时没有进程到达!
第52ms时没有进程到达!
第53ms时没有进程到达!
第54ms时没有进程到达!
第55ms时没有进程到达!
第56ms时没有进程到达!
第57ms时没有进程到达!
第58ms时没有进程到达!
第59ms时没有进程到达!
60ms时A4进程的松弛度为:10
=> 60ms时刻A4进程开始执行: 60 - 70 ms: A4
第70ms时没有进程到达!
第71ms时没有进程到达!
第72ms时没有进程到达!
第73ms时没有进程到达!
第74ms时没有进程到达!
第75ms时没有进程到达!
第76ms时没有进程到达!
第77ms时没有进程到达!
第78ms时没有进程到达!
第79ms时没有进程到达!
80ms时A5进程的松弛度为:10
=======执行只考虑前80ms,现时间已到80ms了!======
**********进程运行完毕!************
是否要结束使用(Y/N)?