做業調度算法

先來先服務、短進程優先算法算法

一.目的

  經過使用c對先來先服務、短進程優先算法的實現,進一步理解並掌握調度算法的邏輯過程,以及每種算法分別在進程調度和做業調度中的的處理方法.ide

二.原理

先來先服務:該算法在每次調度中,都是從後備做業隊列中選擇一個或多個最早進入該隊列的做業,將它們調入內存,爲他們分配資源、建立進程,而後放入就緒隊列。在進程調度中採用FCFS算法時,則每次調度是從就緒隊列中選擇一個最早進入該隊列的進程,位置分配處理機,使之投入運行。該進程一直運行到完成或發生某事件而阻塞後才放棄處理機。函數

短進程優先:該調度算法是從後備序列中選擇一個或若干個估計運行時間最短的做業,將他們調入內存運行。測試

三.流程圖

wKioL1abTA_gTdZqAAAbFiNK1R8980.png

wKiom1abS-_D_u2oAAAXr9X5sxE613.png

四.程序清單

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define getpch(type) (type*)malloc(sizeof(type)) 
int n; 
float T1=0,T2=0;
int times=0;   
  
struct jcb      //做業控制塊 
{   
    char name[10];  //做業名  
    int reachtime;   //做業到達時間  
    int starttime;    //做業開始時間   
    int needtime;       //做業須要運行的時間 
    int finishtime;       //做業完成時間  
    float cycletime;       //做業週轉時間  
    float cltime;           //做業帶權週轉時間 
    char state;            //做業狀態 
    struct jcb *next;      //結構體指針
}*ready=NULL,*p,*q; 
  
typedef struct jcb JCB; 
  
void inital()   //創建做業控制塊隊列,先將其排成先來先服務的模式隊列
{
    int i;
    printf("\n輸入做業數:");
    scanf("%d", &n);
    for (i = 0; i<n; i++)    
    {
        p = getpch(JCB);       
        printf("\n輸入做業名:");         
        scanf("%s", p->name);      
        getchar();        
        p->reachtime = i;       
        printf("做業默認到達時間:%d", i);      
        printf("\n輸入做業要運行的時間:");      
        scanf("%d", &p->needtime);    
        p->state = 'W';    
        p->next = NULL;       
        if (ready == NULL)  
        ready = q = p;      
        else
        { 
                q->next = p;        
                q = p; 
        } 
    }
}
  
void disp(JCB*q,int m)    //顯示做業運行後的週轉時間及帶權週轉時間等
{
    printf("\n做業%s正在運行,估計其運行狀況:\n",q->name);   
    printf("開始運行時刻:%d\n",q->starttime);    
    printf("完成時刻:%d\n",q->finishtime); 
    printf("週轉時間:%f\n",q->cycletime);  
    printf("帶權週轉時間:%f\n",q->cltime);   
    getchar();  
}
  
void running(JCB *p, int m)  //運行做業
{
    if (p == ready)          //先將要運行的做業從隊列中分離出來 
    {
    ready = p->next;
    p->next = NULL;
    }
    else
    {
        q = ready;
        while (q->next != p)  q = q->next;
        q->next = p->next;
    }
    p->starttime = times;    //計算做業運行後的完成時間,週轉時間等等 
    p->state = 'R';
    p->finishtime = p->starttime + p->needtime;
    p->cycletime = (float)(p->finishtime - p->reachtime);
    p->cltime = (float)(p->cycletime / p->needtime);
    T1 += p->cycletime;
    T2 += p->cltime;
    disp(p, m);        //調用disp()函數,顯示做業運行狀況     
    times += p->needtime;
    p->state = 'F';
    printf("\n%s has been finished!\n", p->name);
    free(p);          //釋放運行後的做業 
    getchar();
}
  
void final() //最後打印做業的平均週轉時間,平均帶權週轉時間 
{    
    float s,t;   
    t=T1/n;  
    s=T2/n;   
    getchar();   
    printf("\n\n做業已經所有完成!\n");   
    printf("\n%d個做業的平均週轉時間是:%f",n,t);   
    printf("\n%d個做業的平均帶權週轉時間是%f:\n\n\n",n,s); 
} 
 
void sjf(int m)      // 最短做業優先算法
{     
    JCB *min;  
    int i,iden;  
    system("cls");    
    inital();   
    for(i=0;i<n;i++)
    {          
        p=min=ready;
        iden=1;  
        do{       
                if(p->state=='W'&&p->reachtime<=times)     
                if(iden)
                {                  
                    min=p;
                    iden=0;    
                }              
                else if(p->needtime<min->needtime) min=p;          
                p=p->next;     
            } while (p != NULL);
        if(iden)
        {        
            i--;  
            times++;      
            if (times>100)
            { 
                printf("\nruntime is too long...error"); 
                getchar(); 
            }
        }
        else
        {
            running(min, m);      
        }    
    }    
    final();      
} 
 
void fcfs(int m)     //先來先服務算法
{ 
 
    int i, iden;   
    system("cls");    
    inital();     
    for (i = 0; i<n; i++)  
    {
 
        p = ready;
        iden = 1;    
        do {
            if (p->state == 'W'&&p->reachtime <= times)  iden = 0;          
            if (iden)p = p->next;
        } while (p != NULL&&iden);
 
       if (iden)           
        {
            i--;     
            printf("\n沒有知足要求的進程,需等待");         
            times++;          
            if (times>100)
            { 
                    printf("\n時間過長"); 
                    getchar();
            }
        }
        else
        {
            running(p, m);  
        }     
    }   
    final();      
} 
 
void menu()
{
    int m;   
    system("cls");                   
printf("\n\n\t\t*********************************************\t\t\n"); printf("\t\t\t\t做業調度演示\n"); printf("\t\t*********************************************\t\t\n"); printf("\n\n\n\t\t\t1.先來先服務算法."); printf("\n\t\t\t2.最短做業優先算法."); printf("\n\t\t\t0.退出程序."); printf("\n\n\t\t\t\t選擇所要操做:"); scanf("%d", &m); switch (m) { case 1: fcfs(m); getchar(); system("cls"); break; case 2: sjf(m); getchar(); system("cls"); break; case 0: system("cls"); break; default: printf("選擇錯誤,從新選擇."); getchar(); system("cls"); menu(); } } int main() { menu(); system("pause"); return 0; }

五.結果截圖

wKiom1abTI_BAn54AAAPJLxG6os388.png

1.先來先服務算法:指針

wKiom1abTOnQQGMwAAAZyWJBVGo126.png

wKioL1abTS_ylOrVAAAbMASswfE463.png

wKiom1abTQnCLw1gAAAGeUhRfKY053.png

2.短做業優先算法:blog

wKioL1abTXqy4oU6AAAyQgKQj-A369.png

wKiom1abTVKAEnWQAABG9PzpZ9w903.png

wKioL1abTZbTnGLqAABE-gUlWxo888.png

wKiom1abTW-waphyAABMibs3p50395.png

六.結果分析

  先來先服務算法比較有利於長做業,而不利於短做業。根據先來先服務的實驗,短做業C的帶權週轉時間竟高達100,這是不能容忍的;而長做業D的帶權週轉時間僅爲1.99。就此可知,先來先服務算法有利於CPU繁忙型做業,而不利於I/O繁忙型做業。隊列

  根據測試結果得知,短做業優先調度算法能有效的下降做業的平均等待時間,提升吞吐量。但同時,該算法對長做業不利,更嚴重的是,若是有一長做業進入系統的後備隊列,因爲調度程序老是優先調度那些短做業,將致使長做業長期不被調度。該算法徹底未考慮做業的緊迫程度,於是不能保證緊迫性做業會被及時處理。進程

相關文章
相關標籤/搜索