从输入井中选择作业读入内存,使其获得处理器,得到运行的机会,即为作业调度。输入井中的作业用“作业控制块”(JCB)标识,为了进行作业调度,将作业控制块组成一个队列,这个队列称为后备队列。
模拟实验中没有实际作业,作业控制块中的信息内容只使用模拟实验中需要的数据。作业控制块中包括作业名、作业大小、所需打印机台数、所需磁带机数量、作业估计执行时间、作业等待时间、指向下一个作业控制块的指针等内容。将作业控制块组成一个队列,实验中采用动态链表的方式模拟作业的后备队列。作业控制块采用结构型数据模拟。
模拟实验中,主存采用可移动的可变分区管理方法,即只要主存空闲区总和比作业大就可以满足作业对主存的需求。对打印机和磁带机这两种独占设备采用静态分配法,即作业执行前必须获得所需资源,并且执行完才归还。
实验中作业的调度采用响应比高者优先算法。响应比为作业的等待时间和作业估计执行时间之比。首先计算出输入井中满足条件的作业的响应比,从中选择响应比最高的一个作业装入主存储器,分配资源。由于是模拟实验,可将作业控制块出队装入主存储器的工作用输出作业名模拟,同时修改系统的资源数量。
模拟实验时,可以首先假设系统的资源情况。假设系统资源只有主存64MB、磁带机4台、打印机2台,然后手工输入某个时刻输入井中的各个作业情况,最后进行作业调度,并将结果输出。
批处理系统中的作业调度模拟程序主要由创建作业队列的程序段(在主函数中)和作业调度函数组成。要求能够编写创建作业队列的程序段和作业调度函数。
<程序设计〉
源程序:
系统中主要数据结构和变量的意义见注释。
#include "stdlib.h"
typedef struct jcb
{char name[4];/*作业名*/
int length; /*作业长度,所需主存大小*/
int printer; /*作业执行所需打印机的数量*/
int tape; /*作业执行所需磁带机的数量*/
int runtime; /*作业估计的执行时间*/
int waittime; /*作业在输入井中的等待时间*/
struct jcb *next;/*指向下一个作业控制块的指针*/
}JCB; /*作业控制块类型定义*/
JCB *head; /*作业队列头指针定义*/
int tape,printer;
long memory;
shedule( )/*作业调度函数*/
{float xk,k;
JCB *p,*q,*s,*t;
do
{p=head;
s=NULL;
q=NULL;
k=0;
while(p!=NULL)
{if(p->length<=memory&&p->tape<=tape&&p->printer<=printer)
{/*系统可用资源是否满足作业需求*/
xk=(float)(p->waittime)/p->runtime;
if(q==NULL||xk>k) /*满足条件的第一个作业或者作业q的响应比小于作业p的响应比*/
{k=xk; /*记录响应比*/
q=p;
t=s;
}/*if*/
}/*if*/
s=p;
p=p->next;/*指针p后移*/
}/*while*/
if(q!=NULL)
{if(t==NULL)/*是作业队列的第一个*/ head=head->next;
else t->next=q->next;/*为作业q分配资源:分配主存空间;分配磁带机;分配打印机;*/
memory=memory-q->length;
tape=tape-q->tape;
printer=printer-q->printer;
printf("选中作业的作业名:%s/n",q->name);
}
}while(q!=NULL);}/*作业调度函数结束*/
main( )
{int i;
char name[4];
int size,tcount,pcount,wtime,rtime;
JCB *p;/*系统数据初始化*/
memory=65536;
tape=4;
printer=2;
head=NULL;
printf("输入作业相关数据(以作业大小为负数停止输入):/n");/*输入数据,建立作业队列*/
printf("输入作业名、作业大小、磁带机数、打印机数、等待时间、估计执行时间/n");
scanf("%s%d%d%d%d%d",name,&size,&tcount,&pcount,&wtime,&rtime);
while(size!=-1)
{/*创建JCB*/
p=(JCB*)malloc(sizeof(JCB));/*填写该作业相关内容*/
strcpy(p->name,name);
p->length=size;
p->printer=pcount;
p->tape=tcount;
p->runtime=rtime;
p->waittime=wtime;/*挂入作业队列队首:*/
p->next=head;
head=p;/*输入一个作业数据*/
printf("输入作业名、作业大小、磁带机数、打印机数、等待时间、估计执行时间/n");
scanf("%s%d%d%d%d%d",name,&size,&tcount,&pcount,&wtime,&rtime);
}/*while*/
shedule( );/*进行作业调度*/
}/*main( )结束*/