作业调度

来源:互联网 发布:小区物业管理系统源码 编辑:程序博客网 时间:2024/05/22 17:40

一、 实验目的
用高级语言编写和调试一个或多个作业调度的模拟程序,以加深对作业调度算法的理解。

二、 实验内容
1. 写并调试一个单道处理系统的作业等待模拟程序。
2. 作业等待算法:分别采用先来先服务(FCFS)、响应比高者优先(HRN)的调度算法。
3. 由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的 CPU时限等因素。
4. 每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。每个作业的最初状态总是等待W。
5. 对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间。

三、实现思路
通过自己编写一个文件并键入作业信息,程序读取文件信息计算长度,之后连接好链表并将文件信息(包括文件名,运行时间,到达时间)存入存储链表;然后在循环中调用检查函数每次显示正在运行的进程和等待进程,同时将已到达的进程放入另一个可运行链表;同时对可运行链表运行执行进程,将运行完的进程放入结构数组存储,接着调用排序函数,最后链表指向下一项,该循环运行直到到达链表结尾;最后,调用显示函数显示要求的信息。高响应比

通过自己编写一个文件并键入作业信息,程序读取文件信息计算长度,之后连接好链表并将文件信息(包括文件名,运行时间,到达时间,优先级)存入存储链表;这了的优先级在两个作业同时到达时起作用。然后在循环中调用检查函数每次显示正在运行的进程和等待进程,将运行完的进程放入结构数组存储,接着调用排序函数,最后链表指向下一项,该循环运行直到到达链表结尾;最后,调用显示函数显示要求的信息。 先来先服务

四、主要的数据结构
结构链表,txt文件。
struct pcb /* 定义进程控制块PCB */
{
char name[namelen];
char state; // 状态
double super; // 优先级
int ntime; // 需要运行时间
int rtime; // 实际运行时间
int betime;// 开始时间
int fintime;//结束时间
int artime; //到达时间
int in; //是否在可运行链表中
struct pcb * link; // 链指针
}; // 高响应比

struct JCB /* 定义进程控制块JCB */
{
char name[namelen];
char state; // 状态
int ntime; // 需要运行时间
int rtime; // 实际运行时间
int betime;// 开始时间
int fintime;//结束时间
int artime; //到达时间
struct JCB * link; // 链指针
};// 先来先服务

五、代码:
先来先服务:

// HRRN algorithm#include <stdio.h>#include <stdlib.h>#include <string.h>#define namelen 10#define bufsize 20struct JCB   /* 定义进程控制块PCB */{    char name[namelen];    char state; // 状态    int ntime; // 需要运行时间    int rtime; // 实际运行时间    int betime;// 开始时间    int fintime;//结束时间    int artime; //到达时间    struct JCB * link; // 链指针};int link ( struct JCB * jcblist, int len){    int i;    jcblist[len].link = NULL;    for ( i = len; i > 0; i--)        jcblist[i-1].link = &jcblist[i];    return 1;}int check ( struct JCB * jcblist, int *curtime ){    struct JCB * temp;    while ( jcblist->link != NULL )    {        if ( jcblist->artime > *curtime ) // no arrived jobs        {            printf ("No arrived jobs.\n");            return 0;        }        else        {            printf ( "The executing job:%s\n", jcblist->name);            break;        }        jcblist = jcblist->link;    }    temp = jcblist+1;    if ( temp->artime > *curtime )    {        printf ( "No jobs in waiting queue.\n");        return 0;    }    else    {        printf ( "In waiting queue:\n");        while ( temp->artime <= *curtime &&  temp->link != NULL )        {            disp( temp );            temp = temp->link;        }    }    return 1;}int sort ( struct JCB * jcblist ) // insertion sort{    int i, j, pl = 0;    for ( ; jcblist[pl].link != NULL && jcblist[pl].link->ntime != 0; pl++ )        ; // the length of the current jcblist    if ( pl == 0 || pl == 1)    {        printf ( "Nothing!\n");        return 0;    }    struct JCB * temp = (struct JCB *)malloc( sizeof( struct JCB));    for ( i = 1; i < pl && jcblist[i].ntime != 0; i++ ) // use insertion sort    {        j = i;        strcpy(temp->name, jcblist[i].name),               temp->ntime = jcblist[i].ntime,temp->artime = jcblist[i].artime ;        while ( j > 0 && temp->artime < jcblist[j-1].artime )        {            strcpy(jcblist[j].name, jcblist[j-1].name),                   jcblist[j].ntime = jcblist[j-1].ntime,jcblist[j].artime = jcblist[j-1].artime ;            j--;        }        strcpy(jcblist[j].name, temp->name),               jcblist[j].ntime = temp->ntime, jcblist[j].artime = temp->artime;    }    free ( temp );    return 1;}int running ( struct JCB * p, struct JCB store[], int * arrlen, int * curtime ){    printf ( "running...\n");    if ( p->rtime == 0 )        p->betime = *curtime;    while ( p->rtime < p->ntime )        p->rtime = p->rtime + 1, *curtime = *curtime + 1; // 运行时间    if ( p->rtime == p->ntime ) // 运行时间等于需要时间    {        p->state = 'F', p->fintime = *curtime;        strcpy(store[*arrlen].name, p->name), store[*arrlen].ntime = p->ntime;        store[*arrlen].rtime = p->rtime, store[*arrlen].state = p->state;        store[*arrlen].betime = p->betime;        store[*arrlen].fintime = p->fintime, store[*arrlen].artime = p->artime;        *arrlen = *arrlen+1;        printf ( "Job:%s finished.\n\n\n", p->name);    }    return 1;}int disp ( struct JCB * pr){    printf(" qname \t state \t ndtime \n");    printf(" |%s\t", pr->name);    printf(" |%c\t", pr->state);    printf(" |%d\t", pr->ntime);    printf("\n");    return 1;}int showresult ( struct JCB * store, int pcblen ){    int arrlen;    double tatime = 0.0, tatimewe = 0.0;    for ( arrlen = 0; arrlen < pcblen; arrlen++ )    {        printf("\n qname \t state \t ndtime  btime \t endtime runtime artime 周转时间 带权周转时间\n");        printf(" |%s\t", store[arrlen].name);        printf(" |%c\t", store[arrlen].state);        printf(" |%d\t", store[arrlen].ntime);        printf(" |%d\t", store[arrlen].betime);        printf(" |%d\t", store[arrlen].fintime);        printf(" |%d\t", store[arrlen].rtime);        printf(" |%d\t", store[arrlen].artime);        printf(" |%d\t", store[arrlen].fintime - store[arrlen].artime);        printf(" |%f\t", (double)( store[arrlen].fintime - store[arrlen].artime )/ store[arrlen].ntime);        printf("\n");        tatime += store[arrlen].fintime - store[arrlen].artime;        tatimewe +=( store[arrlen].fintime - store[arrlen].artime )/ store[arrlen].ntime;    }    printf ( "\n平均周转时间 \t 带权周转时间\n");    printf ( "|%f\t", tatime / pcblen );    printf ( "|%f\t", tatimewe / pcblen);}int main ( void ){    int i, j = 0, pcbnum = 0, curtime = 0, arrlen = 0;// job's number, current time store array's length counter    int pcblen = 0, filechar;// arrlen: the length of store    char * buffer = (char *)malloc( sizeof(char) * bufsize); // the buffer    FILE * infor = fopen( "test.txt", "r");    while ( (filechar = fgetc(infor)) != EOF)        if ( filechar == '\n')            pcblen++;    pcblen += 1; // get the length of the file.    struct JCB * jcblist = (struct JCB *)malloc( sizeof ( struct JCB)* pcblen);// allocate memory for the jobs    struct JCB * store = (struct JCB *)malloc( sizeof ( struct JCB)* pcblen); // store list    struct JCB * location1 = (struct JCB *)malloc(sizeof ( struct JCB));    location1 = jcblist;    link ( jcblist, pcblen);// link the pcblist arrpcb    rewind( infor );    // file information assignment    while ( fgets(buffer, bufsize, infor) != NULL )    {        for ( i = 0; buffer[i] != ' '; i++ ) // name assignment            jcblist[pcbnum].name[i] = buffer[i];        jcblist[pcbnum].name[i] = '\0';        jcblist[pcbnum].ntime = atoi(buffer + i); // ntime assignment        i++;        for ( ; buffer[i] != ' '; i++ )            ;        jcblist[pcbnum].artime = atoi( buffer + i);        jcblist[pcbnum].state = 'W', jcblist[pcbnum].rtime = 0;        pcbnum++;    }    sort ( jcblist );    while ( j < pcblen )    {        printf ( "Current time:%d\n", curtime);        check ( jcblist + j, &curtime ); // the header of arrpcb        running( jcblist+j, store, &arrlen, &curtime ); // also calculate the super        j++;    }    printf("\n\n All jobs have finished.\n");    showresult ( store, pcblen );    fclose( infor );    free ( location1 ), free( store );    return 0;}

高响应比:

// HRRN algorithm#include <stdio.h>#include <stdlib.h>#include <string.h>#define namelen 10#define bufsize 20struct pcb   /* 定义进程控制块PCB */{    char name[namelen];    char state; // 状态    double super; // 优先级    int ntime; // 需要运行时间    int rtime; // 实际运行时间    int betime;// 开始时间    int fintime;//结束时间    int artime; //到达时间    int in;     //是否在可运行链表中    struct pcb * link; // 链指针};int link ( struct pcb * pcblist, int len){    int i;    pcblist[len].link = NULL;    for ( i = len; i > 0; i--)        pcblist[i-1].link = &pcblist[i];    return 1;}int check ( struct pcb * pcblist, struct pcb * arrpcb, int *curtime, int * arrpcblen, int * j ){    int plco = 0, i = *j;// i record the current loc    while ( pcblist[plco].link != NULL ) // put the arrived jobs into arrpcb    {        if ( pcblist[plco].in == 0 && pcblist[plco].artime <= *curtime && pcblist[plco].link != NULL)        {            arrpcb[*arrpcblen].ntime = pcblist[plco].ntime, strcpy(arrpcb[*arrpcblen].name, pcblist[plco].name);            arrpcb[*arrpcblen].state = 'W', *arrpcblen = *arrpcblen + 1;            pcblist[plco].in = 1, arrpcb[*arrpcblen].artime = pcblist[plco].artime;        }        plco++;    }    if ( arrpcb[i].ntime == 0 )    {        printf ( "No arrive jobs!\n");        return 0;    }    struct pcb * temppcb2 = arrpcb->link; // calculate the super    while (temppcb2->link != NULL && temppcb2->ntime != 0)    {        temppcb2->super = ((double)*curtime - (double)(temppcb2->artime)) / ( ((double)*curtime - (double)(temppcb2->artime)) + temppcb2->ntime);// 完成一个任务后更新优先级;        temppcb2 = temppcb2->link;    }    sort(arrpcb + i);    printf ( "\n The execute job :\n");    arrpcb[i].state = 'R';// change the running job's state    disp( arrpcb+i );    struct pcb * temppcb1; // show the waiting queue    temppcb1 = arrpcb[i].link;    if ( temppcb1->link != NULL && temppcb1->ntime != 0  ) // show the jobs in the waiting queue        printf("\n The jobs in waiting queue:\n");    while ( temppcb1->link != NULL && temppcb1->ntime != 0 )    {        disp ( temppcb1 );        temppcb1 = temppcb1->link;    }    return 1;}int sort ( struct pcb * arrpcb ) // insertion sort{    int i, j, pl = 0;    for ( ; arrpcb[pl].link != NULL && arrpcb[pl].link->ntime != 0; pl++ )        ; // the length of the current arrpcb    if ( pl == 0 || pl == 1)        return 0;    //printf ( "The current of the list:%d\n", pl);    struct pcb * temp = (struct pcb *)malloc( sizeof( struct pcb));    for ( i = 1; i < pl && arrpcb[i].ntime != 0; i++ ) // use insertion sort    {        j = i;        temp->super = arrpcb[i].super, strcpy(temp->name, arrpcb[i].name),              temp->ntime = arrpcb[i].ntime;        while ( j > 0 && temp->super > arrpcb[j-1].super )        {            arrpcb[j].super = arrpcb[j-1].super, strcpy(arrpcb[j].name, arrpcb[j-1].name),                      arrpcb[j].ntime = arrpcb[j-1].ntime;            j--;        }        arrpcb[j].super = temp->super, strcpy(arrpcb[j].name, temp->name),                  arrpcb[j].ntime = temp->ntime;    }    free ( temp );    return 1;}int running ( struct pcb * p, struct pcb store[], int * arrlen, int * curtime ){    if ( p->rtime == 0 )        p->betime = *curtime;    while ( p->rtime < p->ntime )        p->rtime = p->rtime + 1, *curtime = *curtime + 1; // 运行时间    if ( p->rtime == p->ntime ) // 运行时间等于需要时间    {        p->state = 'F', p->fintime = *curtime;        strcpy(store[*arrlen].name, p->name), store[*arrlen].ntime = p->ntime;        store[*arrlen].rtime = p->rtime, store[*arrlen].state = p->state;        store[*arrlen].super = p->super, store[*arrlen].betime = p->betime;        store[*arrlen].fintime = p->fintime, store[*arrlen].artime = p->artime;        *arrlen = *arrlen+1;        printf ( "Job:%s finished.\n", p->name);    }    return 1;}int disp ( struct pcb * pr){    printf(" qname \t state \t ndtime \n");    printf(" |%s\t", pr->name);    printf(" |%c\t", pr->state);    printf(" |%d\t", pr->ntime);    printf("\n");    return 1;}int showresult ( struct pcb * store, int pcblen ){    int arrlen;    double tatime = 0.0, tatimewe = 0.0;    for ( arrlen = 0; arrlen < pcblen; arrlen++ )    {        printf("\n qname \t state \t ndtime  btime \t endtime runtime artime 周转时间 带权周转时间\n");        printf(" |%s\t", store[arrlen].name);        printf(" |%c\t", store[arrlen].state);        printf(" |%d\t", store[arrlen].ntime);        printf(" |%d\t", store[arrlen].betime);        printf(" |%d\t", store[arrlen].fintime);        printf(" |%d\t", store[arrlen].rtime);        printf(" |%d\t", store[arrlen].artime);        printf(" |%d\t", store[arrlen].fintime - store[arrlen].artime);        printf(" |%f\t", (double)( store[arrlen].fintime - store[arrlen].artime )/ store[arrlen].ntime);        printf("\n");        tatime += store[arrlen].fintime - store[arrlen].artime;        tatimewe +=( store[arrlen].fintime - store[arrlen].artime )/ store[arrlen].ntime;    }    printf ( "\n平均周转时间 \t 带权周转时间\n");    printf ( "|%f\t", tatime / pcblen );    printf ( "|%f\t", tatimewe / pcblen);}int main ( void ){    int i, j = 0, pcbnum = 0, curtime = 0, arrlen = 0;// job's number, current time store array's length counter    int pcblen = 0, filechar, arrpcblen = 0;// arrlen: the length of store    char * buffer = (char *)malloc( sizeof(char) * bufsize); // the buffer    FILE * infor = fopen( "test.txt", "r");    while ( (filechar = fgetc(infor)) != EOF)        if ( filechar == '\n')            pcblen++;    pcblen += 1; // get the length of the file.    struct pcb * pcblist = (struct pcb *)malloc( sizeof ( struct pcb)* pcblen);// allocate memory for the jobs    struct pcb * store = (struct pcb *)malloc( sizeof ( struct pcb)* pcblen); // store list    struct pcb * arrpcb = (struct pcb *)malloc( sizeof ( struct pcb)* pcblen); // arrived jobs    struct pcb * location1 = (struct pcb *)malloc(sizeof ( struct pcb));    struct pcb * location2 = (struct pcb *)malloc(sizeof ( struct pcb));    memset( arrpcb, 0, sizeof(struct pcb) * pcblen );    location1 = pcblist, location2 = pcblist;    link ( pcblist, pcblen),  link ( arrpcb, pcblen);// link the pcblist arrpcb    rewind( infor );    // file information assignment    while ( fgets(buffer, bufsize, infor) != NULL )    {        for ( i = 0; buffer[i] != ' '; i++ ) // name assignment            pcblist[pcbnum].name[i] = buffer[i];        pcblist[pcbnum].name[i] = '\0';        pcblist[pcbnum].ntime = atoi(buffer + i); // ntime assignment        i++;        for ( ; buffer[i] != ' '; i++ )            ;        pcblist[pcbnum].artime = atoi( buffer + i);        pcblist[pcbnum].state = 'W', pcblist[pcbnum].rtime = 0;        pcblist[pcbnum].super = 1.0, pcblist[pcbnum].in = 0;        pcbnum++;    }    while ( j < pcblen )    {        printf ( "\nCurrent time:%d", curtime);        check ( pcblist, arrpcb, &curtime, &arrpcblen, &j ); // the header of arrpcb        running( arrpcb + j, store, &arrlen, &curtime );// also calculate the super        sort(arrpcb+j+1);        j++;        i = 0;    }    printf("\n\n All jobs have finished.\n");    showresult ( store, pcblen );    free ( location1 ), free( location2 ), free( store );    return 0;}

对比:
高响应比:结构体较为复杂,代码实现较为复杂,思路也相对复杂一些,每次运行完需要更新每个作业的优先级别,运行时间相对会多一些。(例子中数据比较少,因此区别不大)
同时,很明显,平均周转时间和带权周转时间相对小。
先到先服务:结构体相对简单,代码简单些,只需要一次排序(代码中对同一时间到达的作业按输入顺序执行)。运行时间较短。最后,平均周转时间和带权周转时间相对较大。
总结:从运行结果可以看出,对于不多的输入数据,高响应比和先到先服务对作业的调度时间相差不大;但对于较多的输入数据,高响应比会比先到先服务的调度时间少。同时,高响应比作业调度方面因为是动态优先级会比先到先得更加合理。