实验2

一、目的和要求

1. 实验目的

(1)加深对作业调度算法的理解;

(2)进行程序设计的训练。

2.实验要求

用高级语言编写一个或多个作业调度的模拟程序。

单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。

     作业调度算法:

1)       采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。

2)       短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。

3)       响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间

每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。

    作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。

一、       模拟数据的生成

1.           允许用户指定作业的个数(2-24),默认值为5。

2.           允许用户选择输入每个作业的到达时间和所需运行时间。

3.           (**)从文件中读入以上数据。

4.           (**)也允许用户选择通过伪随机数指定每个作业的到达时间(0-30)和所需运行时间(1-8)。

二、       模拟程序的功能

1.           按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。

2.           动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。

3.           (**)允许用户在模拟过程中提交新作业。

4.           (**)编写并调度一个多道程序系统的作业调度模拟程序。 只要求作业调度算法:采用基于先来先服务的调度算法。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。

三、       模拟数据结果分析

1.           对同一个模拟数据各算法的平均周转时间,周转系数比较。

2.           (**)用曲线图或柱形图表示出以上数据,分析算法的优点和缺点。

四、       其他要求

1.           完成报告书,内容完整,规格规范。

2.           实验须检查,回答实验相关问题。

注:带**号的条目表示选做内容。

二、实验内容

根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。

三、实验环境

可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。

四、实验原理及核心算法参考程序段

#include<stdio.h>
#include<stdlib.h>
typedef struct JCB{     //定义进程控制块
 char name[10];
 char state;
 int tt;       //提交时间
 int kt;       //开始时间
 int jt;       //结束时间
 int nt;       //运行需要时间
 int st;       //运行了一段时间后被抢占资源,还需要的时间
 int priority;     //优先级
 float yt;      //实际运行时间
 float jqyt;      //加权运行时间
 char depend[10];    //完成的前提作业
 struct JCB *next;    //指向下个作业
}jcb;
    int time=10000,n,flag;        //计时器
             //flag标志当前作业剩余量
char k;
jcb *head=NULL,*p,*q;
    run_fcfo(jcb *p1)
{
        time=p1->tt<time?p1->tt:time;
 printf("
现在时间是%d,开始运行作业%s!
",time,p1->name);
 printf("
name	tt	nt	jt	prt	depend	yt	jqyt
");
 time+=p1->nt;
 p1->yt=time-p1->tt;
 p1->jqyt=p1->yt/p1->nt;
 p1->state='F';
 p1->jt=time;
 printf("%s	%d	%d	%d	%d	%s	%.1f	%.1f
",p1->name,p1->tt,p1->nt,p1->jt,p1->priority,p1->depend,p1->yt,p1->jqyt);
 printf("
作业%s已经运行结束!共费时%0.1f!
",p1->name,p1->yt);
}
    sata()        //统计数据
{
 int i;
 float sum=0,jqsum=0;   //分别存放总运行时间和加权时间
 p=head;
 for(i=0;i<n;i++)
 {
  sum+=p->yt;
  jqsum+=p->jqyt;
  p=p->next;
 }
 printf("
所有作业全部运行完毕!
");
 printf("
平均周转时间为:%0.2f

平均加权周转时间为:%0.2f
",sum/n,jqsum/n);
}
fcfo()
{
 int i,j,t; 
     //t作为当前提交时间的存储值
 for(j=0;j<n;j++)
 {
  p=head; 
  t=10000;
  for(i=0;i<n;i++)  //找到当前未完成的作业
  {
   
   if(p->tt<t&&p->state=='W')
   {
    t=p->tt;
    q=p;    //标记当前未完成的作业
   }
   p=p->next;
  }
  run_fcfo(q);
 }
 //下面统计数据
 sata();
}
    run_sjf(jcb *p1)
{
 //p1-<yt=time-p1-<tt+1;
 if(p1->st==p1->nt)
 {
  p1->kt=time;     //如果尚未运行过,确定运行开始时间
 }
 if(p1->st-1==0)
 {
  p1->jt=time+1;     //如果运行后可以结束,记录下当前的结束时间
 }
 p1->st--; 
 printf("
时刻:%d",time);
 printf("
name	tt	nt	st	prt
");
 printf("%s	%d	%d	%d	%d
",p1->name,p1->tt,p1->nt,p1->st,p1->priority);
 if(p1->st==0)      //如果某个作业运行结束
 {
  p1->yt=p1->jt-p1->tt;
  printf("


-----------------------------------------------------
");
  printf("-----------------------------------------------------
");
  p1->state='F';
  printf("
作业%s已经完成,作业参数如下:
",p1->name);
  printf("
name	tt	nt	jt	prt	depend	yt	jqyt
");
  p1->jqyt=p1->yt/p1->nt;
  printf("%s	%d	%d	%d	%d	%s	%.1f	%.1f
",p1->name,p1->tt,p1->nt,p1->jt,p1->priority,p1->depend,p1->yt,p1->jqyt);
  printf("-----------------------------------------------------
");
  printf("-----------------------------------------------------


");
  flag--;
 }
}
sjf()
{
 int i;   
 jcb *now=head;       //指向当前运行的作业
 flag=n;
     while(flag)
 {
  p=head,q=head;        //每次循环前将p置于指向作业头
  for(i=0;i<n;i++)
  {   
   if(p->state=='W'&&p->tt<=time)
   {
    if(q->state=='W') q=q->nt<p->nt?q:p;     //执行短进程优先策略
    else q=p;    
   }
   p=p->next;
  }
  if(q->state!='F')
  {
  run_sjf(q);
  }
  else
  {
   printf("
时刻:%d",time);
   printf("
无作业可以运行,等待作业进入!
");
  }
   time++;
 }
 //下面统计数据
 sata();

}
    run_prtf(jcb *p1)
{
 //p1-<yt=time-p1-<tt+1;
 if(p1->st==p1->nt)
 {
  p1->kt=time;     //如果尚未运行过,确定运行开始时间
 }
 if(p1->st-1==0)
 {
  p1->jt=time+1;     //如果运行后可以结束,记录下当前的结束时间
 }
 p1->st--; 
 printf("
时刻:%d",time);
 printf("
name	tt	nt	st	prt
");
 printf("%s	%d	%d	%d	%d
",p1->name,p1->tt,p1->nt,p1->st,p1->priority);
 if(p1->st==0)      //如果某个作业运行结束
 {
  p1->yt=p1->jt-p1->tt;
  printf("


-----------------------------------------------------
");
  printf("-----------------------------------------------------
");
  p1->state='F';
  printf("
作业%s已经完成,作业参数如下:
",p1->name);
  printf("
name	tt	nt	jt	prt	depend	yt	jqyt
");
  p1->jqyt=p1->yt/p1->nt;
  printf("%s	%d	%d	%d	%d	%s	%.1f	%.1f
",p1->name,p1->tt,p1->nt,p1->jt,p1->priority,p1->depend,p1->yt,p1->jqyt);
  printf("-----------------------------------------------------
");
  printf("-----------------------------------------------------


");
  flag--;
 }
}
prtf()     
{
 int i;   
 jcb *now=head;       //指向当前运行的作业
 flag=n;
     while(flag)
 {
  p=head,q=head;        //每次循环前将p置于指向作业头
  for(i=0;i<n;i++)
  {   
   if(p->state=='W'&&p->tt<=time)
   {
    if(q->state=='W') q=q->priority<p->priority?q:p;     //执行优先级优先策略
    else q=p;    
   }
   p=p->next;
  }
  if(q->state!='F')
  {
   run_prtf(q);
  }
  else
  {
   printf("
时刻:%d",time);
   printf("
无作业可以运行,等待作业进入!
");
  }
   time++;
 }
 //下面统计数据
 sata();
}
    run(int i)     //选择相应的模块开始运行
{
 printf("


虚拟机开始运行:
");
 switch(i)
 {
 case 1: fcfo();break;
 case 2: sjf();break;
 case 3: prtf();break;
 default: printf("
运行错误!请检查错误!
");    
 }
 
}
    getit()          //得到进程的相关信息
{
 int num;
 printf("
总共有多少个作业?");
 scanf("%d",&n);
 printf("
现在请输入各进程的详细信息:
各项之间用tab键分隔!
");
 printf("
name	tt	nt	prt	depend
");
 for(num=0;num<n;num++)
 {
  p=(jcb *)malloc(sizeof(jcb));
  if(head==NULL) {head=p;q=p;}
  scanf("%s	%d	%d	%d	%s",&p->name,&p->tt,&p->nt,&p->priority,&p->depend);
  if(p->tt<time) time=p->tt;
  q->next=p;
  p->state='W';
  p->st=p->nt;
  p->yt=0;
  p->next=NULL;
  q=p;          //记录当前P的位置,为下一步定义准备
 }
 printf("输入完毕;
");
}
    startup()         //运行的主程序
{
 int i;
 printf("操作系统作业模拟调度程序:

	1,先进先出调度;
	2,短进程优先调度;
	3,按优先级调度;
");
 printf("请选择:
");
 scanf("%d",&i);
 if(i<3)
 {
  printf("
输入错误,请输入1-3之间的数!
重新开始:
");
  startup();
 }
 getit();
 run(i);
}
    main()
{
 printf("
---------------------生活很美好,奋斗仍继续!(翠连座右铭)----------------------
");
 startup();
 printf("
模拟运行已经完成!
");
}

原文地址:https://www.cnblogs.com/123hcl/p/4483932.html