处理机调度——实时调度算法EDF和RMS…

来源:互联网 发布:幻想武器知乎 编辑:程序博客网 时间:2024/06/05 15:14

实验二 处理机调度——实时调度算法EDFRMS    

一、实验目的

深入理解处理机调度算法,了解硬实时概念,掌握周期性实时任务调度算法EDF(Earliest Deadline First)RMS(Rate Monotonic Scheduling)的可调度条件,并能在可调度情况下给出具体调度结果

二、实验原理

EDF为可抢先式调度算法,其调度条件为sum(Ci/Ti)£1

RMS算法为不可抢先调度算法,其调度条件为sum(Ci/Ti)£n(exp(ln(2)/n)-1)

三、实验内容

Linux环境中采用用户级线程模拟实现EDFRMS两种实时调度算法。给定一组实时任务,按照EDF算法和RMS算法分别判断是否可调度,在可调度的情况下,创建一组用户级线程,分别代表各个实时任务,并按算法确定的调度次序安排各个线程运行,运行时在终端上画出其Gantt图。为避免图形绘制冲淡算法,Gantt图可用字符表示。 

三、实验设计

1、实时任务用task数据结构描述,设计四个函数:select_proc()用于实现调度算法,被选中任务执行proc(),在没有可执行任务时执行idle(),主函数mian()初始化相关数据,创建实时任务并对任务进行调度。

2、为模拟调度算法,给每个线程设置一个等待锁,暂不运行的任务等待在相应的锁变量上。主线程按调度算法唤醒一个子线程,被选中线程执行一个时间单位,然后将控制权交给主线程判断是否需要重新调度。 


 

四、实验代码

 

#include"math.h"

#include"sched.h"

#include"pthread.h"

#include"stdio.h"

#include"stdlib.h"

#include"semaphore.h"


typedefstruct{              //实时任务描述

chartask_id;

int call_num;              //任务发生次数

int ci;                    //任务处理时间

int ti;                    //任务发生周期

intci_left;

int ti_left;//record the reduction of ti \ci

int flag;                  //任务是否活跃,0否,2是

int arg;                   //参数

pthread_t th;                   //任务对应线程

}task;


void proc(int*args);

void*idle();

intselect_proc(int alg);


inttask_num=0;

intidle_num=0;


int alg;                    //所选算法,1for EDF,2 for RMS

intcurr_proc=-1;

intdemo_time=100;            //演示时间


task*tasks;

pthread_mutex_tproc_wait[10];    //the biggestnumber of tasks

pthread_mutex_tmain_wait,idle_wait;

floatsum=0;

pthread_tidle_proc;


int main(intargc,char **argv)

{

pthread_mutex_init(&main_wait , NULL);

pthread_mutex_lock(&main_wait);     //下次执行lock等待

pthread_mutex_init(&idle_wait , NULL);

pthread_mutex_lock(&idle_wait);    //下次执行lock等待

printf("Pleaseinput number of real time task:\n");

intc;

scanf("%d",&task_num);               //任务数

tasks=(task*)malloc(task_num *sizeof(task));

while((c=getchar())!='\n'&& c!=EOF);        //清屏

inti;

for(i=0 ;i<task_num ; i++)

{

pthread_mutex_init(& proc_wait[i] , NULL);

pthread_mutex_lock(& proc_wait[i]);

}


for(i=0;i<task_num;i++)

{

printf("Pleased input taskid,followed by Ci and Ti:\n");

scanf("%c,%d,%d,",&tasks[i].task_id,&tasks[i].ci,&tasks[i].ti);

tasks[i].ci_left=tasks[i].ci; 

tasks[i].ti_left=tasks[i].ti;

tasks[i].flag=2;

tasks[i].arg=i;

tasks[i].call_num=1;

sum=sum+(float)tasks[i].ci/ (float)tasks[i].ti;

while((c=getchar())!='\n'&&c!=EOF); //清屏

}


printf("Pleaseinput algorithm,1 for EDF,2 for RMS:");

scanf("%d",&alg);

printf("Pleaseinput demo time:");

scanf("%d",& demo_time);

double r = 1;          //EDF算法,最早截止期优先调度

 

if(alg ==2)

    //RMS算法,速率单调调度

r=((double)task_num)*(exp(log(2)/(double)task_num)-1);

printf("r is%lf\n",r);

}

if(sum>r)// 综合EDF和RMS算法任务不可可调度的情况  

       //不可调度

printf("(sum=%lf>r=%lf),notschedulable!\n",sum,r);

exit(2);

}

//创建闲逛线程

pthread_create(&idle_proc , NULL , (void*)idle , NULL);


for(i=0;i<task_num ;i++)   //创建实时任务线程

pthread_create(&tasks[i].th,NULL, (void*)proc, &tasks[i].arg);


for(i=0;i<demo_time;i++)

{

intj;

if((curr_proc=select_proc(alg))!=-1)

//按调度算法选择线程

pthread_mutex_unlock(&proc_wait[curr_proc]);   //唤醒

pthread_mutex_lock(&main_wait);              //主线程等待

}

else

   //无可运行任务,选择闲逛线程

pthread_mutex_unlock(&idle_wait);

pthread_mutex_lock(&main_wait);

}


for(j=0;j<task_num;j++)

 //Ti--,直至为0时开始下一周期

if(--tasks[j].ti_left==0)

{

tasks[j].ti_left=tasks[j].ti;

tasks[j].ci_left=tasks[j].ci;

pthread_create(&tasks[j].th,NULL,(void*)proc,&tasks[j].arg);

tasks[j].flag=2;

}

}

}

printf("\n");

sleep(10);

};


void proc(int*args)

{

while(tasks[*args].ci_left>0)

{

pthread_mutex_lock(&proc_wait[*args]);//等待被调度

if(idle_num!=0)

{

printf("idle(%d)",idle_num);

idle_num=0;

}

printf("%c%d",tasks[*args].task_id,tasks[*args].call_num); 

tasks[*args].ci_left--;   //执行一个时间单位

if(tasks[*args].ci_left==0)

{

printf("(%d)",tasks[*args].ci);

tasks[*args].flag=0;

tasks[*args].call_num++;//

}

pthread_mutex_unlock(&main_wait);   //唤醒主线程

}

};



void*idle()

{

while(1)

{

pthread_mutex_lock(&idle_wait); //等待被调度

printf("->");               //空耗一个时间单位

idle_num++;

pthread_mutex_unlock(&main_wait);        //唤醒主线程

}

};


intselect_proc(int alg)

{

intj;

inttemp1,temp2;

temp1=10000;

temp2=-1;

if((alg==2)&&(curr_proc!=-1)&&(tasks[curr_proc].flag!=0))

returncurr_proc;

for(j=0;j<task_num;j++)

{

if(tasks[j].flag==2)

{

switch(alg)

{

case 1:          //EDF算法

if(temp1>tasks[j].ci_left)

{

temp1=tasks[j].ci_left;

temp2=j;

}

case 2:        //RMS算法

if(temp1>tasks[j].ti)

{

temp1=tasks[j].ti;

temp2=j;

}

}

}

}

return temp2;//return the selected thread or task number

};


五、实验结果

处理机调度鈥斺斒凳钡鞫人惴‥DF和RMS

处理机调度鈥斺斒凳钡鞫人惴‥DF和RMS

 

 


 


 

 

 

原创粉丝点击