处理器调度实验报告

时间:2024.4.20

处理器调度

级:10网工三班    学生姓名:谢昊天     学号:1215134046

实验目的和要求:

选择一个调度算法,实现处理器调度。在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。

实验内容与分析设计:

本实验有两个题,学生可选择其中的一题做实验。

第一题:设计一个按优先数调度算法实现处理器调度的程序。

[提示]:

(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:进程名,指针,要求运行时间,优先数,状态

(2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。

(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。

(4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:

优先数-1

要求运行时间-1

来模拟进程的一次运行。

提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。

(5) 进程运行一次后,若要求运行时间?0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。

(6) 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。

(7) 在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。

(8) 为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。

第二题:设计一个按时间片轮转法实现处理器调度的程序。

[提示]:

(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表。进程控制块的格式为:进程名,指针,要求运行时间,已运行时间,状态

(2) 每次运行所设计的处理器调度程序前,为每个进程任意确定它的“要求运行时间”。

(3) 把五个进程按顺序排成循环队列,用指针指出队列连接情况。另用一标志单元记录轮到运行的进程。

(4) 处理器调度总是选择标志单元指示的进程运行。

(5) 进程运行一次后,应把该进程的进程控制块中的指针值送到标志单元,以指示下一个轮到运行的进程。同时,应判断该进程的要求运行时间与已运行时间,若该进程的要求运行时间?已运行时间,则表示它尚未执行结束,应待到下一轮时再运行。若该进程的要求运行时间=已运行时间,则表示它已经执行结束,应指导它的状态修改成“结束”(E)且退出队列。此时,应把该进程的进程控制块中的指针值送到前面一个进程的指针位置。

(6) 若“就绪”状态的进程队列不为空,则重复上面的(4)和(5)的步骤,直到所有的进程都成为“结束”状态。

(7) 在所设计的程序中应有显示或打印语句,能显示或打印每次选中进程的进程名以及运行一次后进程队列的变化。

(8) 为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中的进程名以及进程控制块的动态变化过程。

实验步骤与调试过程:

1.打开vc,新建工程,并建基于控制台的文件

2.确定五个进程并在运行所设计的处理器调度程序前确定每个进程要求运行时间

3.把五个进程按顺序排成循环队列,用指针指出队列连接情况

4.需求分析:了解基本原理,确定程序的基本功能,查找相关资料,画出基本的数据流图;【先来先服务流程图】(开始 -> 初始化说有的JCB 使JCB按作业提交的时刻的先后顺序排队时间量T1=0 -> 调度对首作业投入运行->计算并打印作业i的完成时间Tc,周转时间Ti带权周转时间Wi -> 更改时间量T的值 -> 等待队列空? - > 空 (不空—>调度对首作业投入运行)-> 计算并打印这组作业的平均周转时间及带权平均周转时间 –> 结束);【高优先权流程图】(开始 -> 初始化PCB,输入进程信息 -> 各进程按优先数从高到低排列 -> 就绪队列空? -> (空 -> 结束) 不空 -> 就绪队列进程投入运行 -> 时间片到,运行进程已占用CPU时间+1  -> 运行进程已占用CPU时间已达到所需的运行时间  ->  (已到达 -> 进程完成,撤销该进程) -> 未到达 ->是运行进程的优先数-1 把运行进程插入就绪队列  -> 就绪队列空? ->……  )【按时间片轮转调度】(系统初始化  ->  启动计数器  ->  读取DTMF编码、摘、挂机信号  ->  0→用户编号  ->  所有用户任务以调用?  ->  (没有调用  ->  根据用户编号,子程序号调用相应任务  ->  指向下一用户,编号+1  ->  所有用户任务以调用?  ->  ……) 已调用 ->  发送DTMF编码  ->  定时时间已到?  ->  (没有到  ->  定时时间已到?  ->  ……)  ->  已到  ->  启动计数器)

6.在所设计的程序中应有显示或打印语句,能显示或打印每次选中进程的进程名以及运行一次后进程队列的变化

7.为五个进程任意确定一组“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中的进程名以及进程控制块的动态变化过程。

5.运行测试;


实验结果:

运行后可执行输入总进程个数后,显示出进程名,总运行时间,已运行时间,状态等信息,分别开始运行程序。运行完毕后会显示a进程已运行结束,进程被删除。完成处理器调度试验。

四、疑难与小结:

通过本次试验,我对处理器调度思想有了进一步的了解,通过动手实现其调度算法,更加深刻的理解了时间片轮调度算法与其他几种算法的不同优点。同时,在实验过程中,回顾书本上的理论知识,巩固了我的知识。

1.轮转法就是按一定时间片(记为q)轮番运行各个进程。如果q是一个定值,则轮转法是一种对各进程机会均等的调度方法。

2.优先级调度的基本思想是,把当前处于就绪队列中优先级最高的进程投入运行,而不管各进程的下一个CPU周期的长短和其他因素。

3.先来先服务调度算法:高响应比优先实现进程调度.(用C语言实现), 如果早就绪的进程排在就绪队列的前面,迟就绪的进程排在就绪队列的后面,那么先来先服务(FCFS:first come first service)总是把当前处于就绪队列之首的那个进程调度到运行状态。

4.优先级调度程序:该程序由主程序、构造队列子程序、打印子程序、运行子程序构成。        
5.时间片轮转法程序:在此程序中由于程序比较小,未进行分模块设计。直接采用单一模块。




 


五、主要算法和程序清单:

按时间片轮转法:

#include<iostream>

#include<cstdlib>

using namespace std;

typedef struct PNode {

    struct PNode *next;

    char name[10];

    int ALL_Time;

    int Runed_Time;

    char state;

}* Proc;

int ProcNum;

void InitPCB(Proc &H){

    cout<<"请输入总进程个数:";

    cin>>ProcNum;

    int Num=ProcNum;

    H=(Proc)malloc(sizeof(PNode));

    H->next=NULL;

    Proc p=H;

    cout<<"总进程个数为"<<ProcNum<<" 个,请依次输入相应信\n\n";

    while(Num--){

        p=p->next=(Proc)malloc(sizeof(PNode));

        cout<<"进程名 总运行时间 已运行时间:";

        cin>>p->name>>p->ALL_Time>>p->Runed_Time;

        p->state='R';

        p->next=NULL;

    }

    p->next=H->next;

}

void DispInfo(Proc H){

    Proc p=H->next;

    do{

        if(p->state !='E')

        {

            cout<<"进程名:"<<p->name<<"\t总运行时间:"<<p->ALL_Time

                <<"\t已运行时间:"<<p->Runed_Time

                <<"\t状态:"<<p->state<<endl;

            p=p->next;

        }

        else p=p->next;

    }while (p!=H->next);

}

void SJP_Simulator(Proc &H){

    cout<<endl<<" START \n";

    int flag=ProcNum;

    int round=0;

    Proc p=H->next;

    while (p->ALL_Time >p->Runed_Time){

        round++;

        cout<<endl<<"Round "<<round<<"--正在运行 "<<p->name<<"进程"<<endl;

        p->Runed_Time++;

        DispInfo(H);

        if(p->ALL_Time == p->Runed_Time){

            p->state='E';

            flag--;

            cout<<p->name<<"进程已运行结束,进程被删除!\n";

        }

        p=p->next;

        while (flag &&p->ALL_Time == p->Runed_Time)

            p=p->next;

    }

    cout<<endl<<" END \n";

}

void main(){

    Proc H;

    InitPCB(H);

    DispInfo(H);

    SJP_Simulator(H);

    system("pause");

}

先来先服务法:

#include<stdio.h>

float t,d; /*定义两个全局变量*/

struct /*定义一个结构体数组,包括进程的信息*/

{

int id;

float ArriveTime;

float RequestTime;

float StartTime;

float EndTime;

float RunTime;

float DQRunTime;

int Status;

}arrayTask[4]; /*定义初始化的结构体数组*/

GetTask()/*给结构体数组赋值,输入到达,服务时间*/

{ int i;

float a;

for(i=0;i<4;i++)

{arrayTask[i].id=i+1;

printf("input the number");

printf("input the the ArriveTime of arrayTask[%d]:",i); /*用户输入进程的时间,初始为零 */

scanf("%f",&a);

arrayTask[i].ArriveTime=a;

printf("input the RequestTime of arrayTask[%d]:",i);

scanf("%f",&a);

arrayTask[i].RequestTime=a;

arrayTask[i].StartTime=0;

arrayTask[i].EndTime=0;

arrayTask[i].RunTime=0;

arrayTask[i].Status=0; /*开始默认的标志位零*/

}

}

int fcfs() /*定义FCFS中寻找未执行的进程的最先到达时间*/{

int i,j,w=0; /*在结构体数组中找到一个未执行的进程*/

for(i=0;i<4;i++) {

if(arrayTask[i].Status==0)

{

t=arrayTask[i].ArriveTime;

w=1;

}

if(w==1)

break;

}

for(i=0;i<4;i++) /*查找数组中到达时间最小未执行的进程*/

{

if(arrayTask[i].ArriveTime<t&&arrayTask[i].Status==0)

t=arrayTask[i].ArriveTime;

} /*返回最小到达时间的数组的下标*/

for(i=0;i<4;i++)

{

if (arrayTask[i].ArriveTime==t)

return i;

}

}

int sjf() /*定义FCFS中寻找未执行的进程的最先到达时间*/

{

int i,x=0,a=0,b=0; /*判断是不是第一个执行的进程*/

float g;

for(i=0;i<4;i++)

{

if(arrayTask[i].Status==1)

{g=arrayTask[i].EndTime;

x=1;

}

}

if(x==0) /*第一个执行的进程按FCFS*/

{

t=arrayTask[0].ArriveTime;

for(i=0;i<4;i++)

{

if(arrayTask[i].ArriveTime<t)

{ t=arrayTask[i].ArriveTime;

a=i;

}

}

return a;}

else

{

for(i=0;i<4;i++)

{if(arrayTask[i].EndTime>g)

g=arrayTask[i].EndTime;

}

for(i=0;i<4;i++)

{if(arrayTask[i].Status==0&& arrayTask[i].ArriveTime<=g)

{t=arrayTask[i].RequestTime;

a=i;

b=1;} /*判断有没有进程在前个进程完成前到达*/

}

if(b!=0) /*有进程到达则按SJF*/

{for(i=0;i<4;i++)

{

if(arrayTask[i].Status==0&&arrayTask[i].ArriveTime<=g&&arrayTask[i].RequestTime<t)

{t=arrayTask[i].RequestTime;

a=i;}

}

return a;}

else{ /*否则按FCFS*/

for(i=0;i<4;i++)

{if(arrayTask[i].Status==0)

t=arrayTask[i].ArriveTime;

}

for(i=0;i<4;i++)

{

if(arrayTask[i].Status==0&&arrayTask[i].ArriveTime<t)

{t=arrayTask[i].ArriveTime;

a=i;

}

}

return a;}

}

}

new(int s) /*定义执行进程后相关数据的修改*/

{

int i,g=0;

for(i=0;i<4;i++)

{

if(arrayTask[i].Status==0)

continue;

else

{

g=1;

break;

}

}

if(g==0) /*当处理的是第一个未执行的进程时执行*/

{

arrayTask[s].StartTime=arrayTask[s].ArriveTime;

arrayTask[s].EndTime=arrayTask[s].RequestTime+arrayTask[s].ArriveTime;

arrayTask[s].RunTime=arrayTask[s].RequestTime;

arrayTask[s].Status=1;

g=2;

}

if(g==1) /*当处理的不是第一个未执行的进程时执行*/

{

arrayTask[s].Status=1;

for(i=0;i<4;i++)

{

if(arrayTask[i].Status==1)

d=arrayTask[i].EndTime;

}

for(i=0;i<4;i++) /*查找最后执行的进程的完成时间*/

{

if(arrayTask[i].EndTime>d&&arrayTask[i].Status==1)

d=arrayTask[i].EndTime;

}

if(arrayTask[s].ArriveTime<d) /*判断修改的进程的到达时间是否在前一个执行的进程的完成时间前面*/

arrayTask[s].StartTime=d;

else

arrayTask[s].StartTime=arrayTask[s].ArriveTime;

arrayTask[s].EndTime=arrayTask[s].StartTime+arrayTask[s].RequestTime;

arrayTask[s].RunTime=arrayTask[s].EndTime-arrayTask[s].ArriveTime;

}

arrayTask[s].DQRunTime=arrayTask[s].RunTime/arrayTask[s].RequestTime;

}

Printresult(int j) /*定义打印函数*/

{

printf("%d\t",arrayTask[j].id);

printf("%5.2f\t",arrayTask[j].ArriveTime);

printf("%5.2f\t",arrayTask[j].RequestTime);

printf("%5.2f\t",arrayTask[j].StartTime);

printf("%5.2f\t",arrayTask[j].EndTime);

printf("%5.2f\t",arrayTask[j].RunTime);

printf("%5.2f\n",arrayTask[j].DQRunTime);

}

main()

{ int i,b,k,a,c=0;

int d[4];

clrscr();

printf("\t F. FCFS \n");

printf("\t S. SFJ  \n");

printf("\t Q. EXIT \n");

for(i=0;;i++)

{if(c)

break;

printf("please input the number a:\n");

scanf("%d",&a);

switch(a)

{

case Q: c=1;

break;

case F:printf("please input the different-ArriveTime of arrayTasks\n");

GetTask();

printf("*****************************the result of fcfs\n");

printf("Number\tArrive\tServer\tStart\tFinish\tTurnove\tTake power turnover time\n");

for(b=0;b<4;b++) /*调用两个函数改变结构体数的值*/

{

k=fcfs();

d[b]=k;

new(k);

}

for(b=0;b<4;b++)

Printresult(d[b]);/*调用打印函数打出结果*/

continue;

case S: printf("please input the different-RequestTime of arrayTasks\n");

GetTask();

printf("******************************the result of sjf\n");

printf("Number\tArrive\tRequest\tStart\tEnd\tRun\tDQRun time\n");

for(b=0;b<4;b++)

{

k=sjf();

d[b]=k;

new(k);

}

for(b=0;b<4;b++)

Printresult(d[b]);

continue;

default:printf("the number Error.please input another number!\n");

}

}

}

优先级调度方法:

#include     <stdio.h>  

  #include   "conio.h"  

  typedef   struct   pcb/*定义结构*/  

          {char name[5];  

            struct pcb *next;   

            int   needtime;  

            int   priority;  

            char state[5];  

          }NODE;  

   

  NODE  *create_process(int   n)/*创建队列*/  

        {NODE     *head,*s,*t;  

          int   time,i=0,j;  

          char     pname[5];  

          head=(NODE   *)malloc(sizeof(NODE));  

          printf("please   input   process   name:");  

          scanf("%s",pname);  

          strcpy(head->name,pname);  

          printf("please   input   need   time:");  

          scanf("%d",&time);  

          head->needtime=time;  

          printf("please   input   priority:");  

          scanf("%d",&j);  

          head->priority=j;  

          strcpy(head->state,"ready");  

          head->next=NULL;  

          t=head;  

          for(i=1;i<n;i++)  

              {  s=(NODE *)malloc(sizeof(NODE));  

  printf("please input process name:");  

  getchar();  

  gets(pname);  

  strcpy(s->name,pname);  

  printf("please input need time:");  

  canf("%d",&time);  

  s->needtime=time;  

  printf("please input priority:");  

  scanf("%d",&j);  

  s->priority=j;  

  strcpy(s->state,"ready");  

  s->next=NULL;  

   t->next=s;  

  t=s;  

      }  

   return  head;  

      }  

  pri_process(NODE *p)/*输出进程队列*/  

      {int   i;  

        NODE  *q;  

        q=p->next;  

        printf("\n name\tneedtime\tpriority \t state\n");  

        while(q!=NULL)  

            {printf("%5s\t %2d \t %2d \t  %5s \n",  

              q->name,q->needtime,q->priority,q->state);  

              q=q->next;  

            }  

      }  

  NODE   *order(NODE   head_sort)/*对进程的优先级进行排序*/  

    {NODE   *p,*s,*q,*head,*r,*t;  

      int     m,pr;  

      char     name[5];  

      head=head_sort;  

      p=head->next;  

      r=p;  

      t=p;  

      q=p->next;  

      while(r!=NULL)  

        {   while(q!=NULL)  

            {if(p->priority<q->priority)  

  {m=p->priority;  

    p->priority=q->priority;  

    q->priority=m;  

    strcmp(name,p->name);  

    strcmp(p->name,q->name);  

    strcmp(q->name,name);  

    pr=p->needtime;  

    p->needtime=q->needtime;  

    q->needtime=pr;  

  }  

              p=q;  

              q=q->next;  

            }  

            r=r->next;  

            p=t;  

            q=p->next;  

        }  

      return(head_sort);  

  }  

  main()/*主程序*/  

  {     NODE   *p=NULL,*head=NULL,*m=NULL,*z=NULL,*n=NULL;  

        int   j,time,x=0;  

        char   c,pname[5];  

        clrscr();  

        printf("please input process number!");  

        scanf("%d",&x);  

        p=create_process(x);  

        head->next=p;  

        pri_process(head);  

        getchar();  

        while(x>0)  

            { order(head);  

               m=head->next;  

  strcpy(m->state,"run");  

  if(m->priority>=2)  

        m->priority--;  

        m->needtime--;  

  if(head->next!=NULL)  

        pri_process(head);  

  if(m->needtime==0)  

    {   head->next=m->next;  

          printf("%s   has   finished\n",m->name);  

          free(m);  

        x--;  

    }  

          getchar();     }  

          textmode(C80);  

          textbackground(0);  

          textcolor(4);  

          printf("over!");  

          getchar();  

  } 

更多相关推荐:
处理器调度实验报告

一实验内容按优先数调度算法实现处理器调度二实验目的在采用多道程序设计的系统中往往有若干个进程同时处于就绪状态当就绪进程个数大于处理器数时就必须依照某种策略来决定哪些进程优先占用处理器本实验模拟在单处理器情况下的...

处理器调度实验报告

操作系统实验报告选题名称所在院系专业名称处理器调度计算机科学与技术学院计算机科学与技术学院日语双学位龚德兴徐莉莉张文卿王俏何慧楠刘艳茹朱静君姓名班级指导老师完成时间1202班付老师20xx1111目录一实习内容...

处理器调度算法实验报告

实验三、处理器调度算法实验计本一区队学号:xxxxx一、实习内容选择一个调度算法,实现处理器调度。二、实习目的本实习模拟在单处理器环境下的处理器调度,加深了解处理器调度的工作。三、实习题目第一题:设计一个按优先…

处理器调度实验报告

实验报告实验课程专业年级学号姓名指导教师20xx20xx学年第3学期

操作系统实验报告(处理器调度)

操作系统实验报告学院计算机科学与技术学院姓名班级学号处理器调度120920xx1150109一实习内容选择一个调度算法实现处理器调度二实习目的在采用多道程序设计的系统中往往有若干个进程同时处于就绪状态当就绪进程...

处理器调度实验报告书

实验一处理器调度实习目的在采用多道程序设计的系统中往往有若干个进程同时处于就绪状态当就绪进程个数大于处理器数时就必须依照某种策略来决定哪些进程优先占用处理器本实习模拟在单处理器情况下的处理器调度帮助学生加深了解...

操作系统处理机调度实验报告

处理机调度算法实验报告

操作系统处理机调度实验C语言版(按优先权排序)

中南大学实验名称处理机调度课程名称计算机操作系统学生姓名盛希玲学号0903060215学院信息科学与工程学院专业班级电子信息工程0602完成时间20xx年10月12日目录一实验内容2二实验目的2三实验题目2四基...

操作系统课程设计报告 处理机调度问题

操作系统课程设计学号姓名专业课程指导教师时间成绩目录目录11设计题目与要求错误未定义书签11设计目的错误未定义书签12设计要求错误未定义书签2总体设计思想错误未定义书签21总体设计思想错误未定义书签3功能设计4...

(08信管)进程时间片轮转调度算法--操作系统实验报告

操作系统实验报告进程时间片轮转调度算法一实验题目进程时间片轮转调度算法二实验原理在多道程序系统中一个作业被提交后必须经过处理机调度后方能获得处理机执行对调度的处理又都可采用不同的调度方式和调度算法调度算法是指根...

操作系统实验--处理机调度算法实现

计算机与通信工程学院天津理工大学计算机与通信工程学院实验报告20xx至20xx学年第二学期计算机与通信工程学院2计算机与通信工程学院计算机与通信工程学院计算机与通信工程学院计算机与通信工程学院试验结果1执行结果...

模拟Linux操作系统下处理机调度实验报告

处理机调度一实验目的1了解Linux下Emacs编辑器的使用方法掌握各种常用的键盘操作命令2理解并掌握处理机调度算法二实验内容及要求在采用多道系统的设计程序中往往有若干进程同时处于就绪状态当就绪状态进程数大于处...

处理器调度实验报告(20篇)