作业:作业是一个比程序更广泛的概念,它不仅包含了通常的程序和数据,而且还应配有的一份说明书,系统根据这份说明书对程序上的运行进行控制。在批处理系统中,是以作业为单位从外存调入内存。
作业调度的主要任务:根据JPB中的信息,检测系统中的资源能否满足作业对资源的需求,以及按照一定的调度算法,从外存的后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源。
短作业优先调度算法:以作业时间的长短计算优先级,作业越短,优先级越高。短作业优先相对于先来先服务有着很大的改进,但短作业优先也有很多的不足。短作业优先必须预知作业的时间,短作业优先算法对长作业十分的不利甚至会忽略掉长作业,短作业优先算法不能人机交互,不能保证紧急的作业能够及时执行。
周转时间:从作业提交给操作系统开始到作业完成的这段时间间隔,尽可能使周转时间小也是处理机调度的目标。
周转时间 = 服务时间 + 等待时间 = 完成时间 - 到达时间
带权周转时间:周转时间和对该作业的服务时间的比值。
模拟短作业优先的C代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Max 256
struct Job{ //描述作业信息
char *name;
int need_time;
int come_time;
int time;
double play_time;
double avg_time;
struct Job *next;
Job() //默认构造函数
{
name = NULL;
next = NULL;
time = 0;
come_time = 0;
need_time = 0;
avg_time = 0;
play_time = 0;
}
void copy_job(struct Job *temp) //拷贝函数
{
name = (char *)malloc(sizeof(char) *strlen(temp->name));
strcpy(name,temp->name);
come_time = temp->come_time;
need_time = temp->need_time;
time = temp->time;
play_time = temp->play_time;
avg_time = temp->avg_time;
return;
}
void play_and_avg_time(int end_time) //计算周转时间、带权周转时间
{
double wait_time;
this->play_time = end_time - this->come_time;
wait_time = this->play_time - this->need_time;
avg_time = 1 + (wait_time / need_time);
return;
}
};
int sum; //统计作业的个数
void init_queue(struct Job **head,char *name,int come_time,int need_time) //初始化作业链表
{
struct Job *temp = new Job();
temp->name = (char *)malloc(sizeof(char) * strlen(name));
strcpy(temp->name,name);
temp->come_time = come_time;
temp->need_time = need_time;
temp ->next = (*head)->next;
(*head)->next = temp;
return;
}
void out_one(struct Job *temp) //显示作业信息
{
printf("name: %s\n",temp->name);
printf("come_time: %d\n",temp->come_time);
printf("need_time: %d\n",temp->need_time);
printf("avg_time: %0.1f\n",temp->avg_time);
printf("play_time: %0.1f\n",temp->play_time);
return;
}
void out_one_queue(struct Job *temp,int i)
{
printf("this time = %d, the job over! \n",i);
out_one(temp);
printf("\n");
return;
}
void add_queue(struct Job *temp,struct Job **head_queue) //在队列中添加一个作业
{
struct Job *temp_queue = new Job();
temp_queue->copy_job(temp); //拷贝作业信息
if((*head_queue) ->next == NULL){
(*head_queue) ->next = temp_queue;
return;
}
struct Job *p;
for(p = (*head_queue)->next; p ->next; p = p->next){ //按照作业时间大小及到达时间插入到队列
if(p->next->need_time > temp_queue->need_time){
temp_queue ->next = p ->next;
p ->next = temp_queue;
return;
}
else if(p->next->need_time == temp_queue->need_time){
temp_queue ->next = p ->next ->next;
p->next = temp_queue;
return;
}
}
if(!p ->next)
p ->next = temp_queue;
return;
}
void dele_queue(struct Job *head_queue) //从队列中删除一个作业
{
if(!head_queue ->next)
return;
struct Job *p = head_queue ->next;
head_queue->next = head_queue->next->next;
delete p;
return;
}
void mo_ni(struct Job *head,struct Job **head_queue) //模拟作业,每次循环加一
{
int i = 0,count_job = 0;
while(i >= 0){
for(struct Job *p = head->next; p; p = p->next) //检查该时间点有无作业到达
if(i == p->come_time){ //如果有作业到达,加入作业队列
add_queue(p,head_queue);
}
if((*head_queue)->next){
if((*head_queue)->next->time == (*head_queue)->next->need_time){ //检查作业服务是否完成
(*head_queue)->next->play_and_avg_time(i); //计算周转时间、带权周转时间
out_one_queue((*head_queue)->next,i);
dele_queue((*head_queue)); //从作业队列中删除
count_job++; //作业计数器加1
}
}
if((*head_queue)->next) //作业服务时间计数器加1
(*head_queue) ->next->time ++;
i++;
if(count_job == sum) //所有作业全部完成,结束
return;
}
return;
}
int main(int argc,char *argv[])
{
struct Job *head = new Job();
struct Job *head_queue = new Job();
char name[Max];
int come_time;
int need_time;
FILE *input_file = fopen("C:\\Users\\chenhongyu\\Desktop\\test.txt","r"); //从文件读取作业信息
printf("plase input name come_time need_time,if over plase input [CTRL + Z]\n\n");
while(fscanf(input_file,"%s%d%d",name,&come_time,&need_time) != EOF){
sum++;
init_queue(&head,name,come_time,need_time);
}
mo_ni(head,&head_queue); //模拟作业
return 0;
}