1. 程式人生 > >處理機排程——實時排程演算法EDF和RMS…

處理機排程——實時排程演算法EDF和RMS…

實驗二 處理機排程——實時排程演算法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"

typedef struct{                //實時任務描述

char task_id;

int call_num;                  //任務發生次數

int ci;                         //任務處理時間

int ti;                         //任務發生週期

int ci_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();

int select_proc(int alg);

int task_num=0;

int idle_num=0;

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

int curr_proc=-1;

int demo_time=100;              //演示時間

task *tasks;

pthread_mutex_t proc_wait[10];    //the biggest number of tasks

pthread_mutex_t main_wait,idle_wait;

float sum=0;

pthread_t idle_proc;

int main(int argc,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("Please input number of real time task:\n");

int c;

scanf("%d",& task_num);                 //任務數

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

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

int i;

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 task id,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("Please input algorithm,1 for EDF,2 for RMS:");

scanf("%d",&alg);

printf("Please input 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),not schedulable!\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++)

{

int j;

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);          //喚醒主執行緒

}

};

int select_proc(int alg)

{

int j;

int temp1,temp2;

temp1=10000;

temp2=-1;

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

return curr_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