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

   处理机调度算法实验报告

 

第二篇:操作系统进程调度实验报告

操作系统进程调度实验报告

一.实验目的

         用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的解.
   进程调度时进程管理的主要内容之一,通过设计,编制,调试一个简单的进程调度模拟系统,对进程调度,进程运行状态变换加深理解和掌握。模拟计算机操作系统的进程调度,建立进程控制块PCB,要包含有关进程的描述信息,控制信息以及资源信息.模拟系统根据PCB感知进程的存在和通过PCB中所包含的各项变量的变化,掌握进程所处的状态以达到控制进程活动的目的.要实现进程的状态及其转换,进程的创建与撤消,进程的阻塞与唤醒.用P,V原语操作实现进程互斥.

二.实验要求

       建立进程控制块PCB,用PCB实现进程在运行过程中的一切状态,未创建、就绪、运行、等待、退出.以完成资源的共享,实现进程的同步与互斥.程序要求用p,v操作实现进程互斥.

三.实验平台

      Windows XP 下的Microsoft vitual c++平台

四.所用语言

        Microsoft Visual C++语言

五.机器要求

        Microsoft Windows XP Professional
                   
版本 2002
                  Service Pack

               256MB内存
            SVGA(800×600分辨率,256色或更高级的显示卡
           鼠标或其他相容设备 

六.系统分析

       设计建立四个进程,模拟模拟批处理多道操作系统的进程调度,
进程调度算法,采用最高优先数优先的调度算法.每个进程有一个进程控制块( PCB)表示。进程控制块可以包含如下信息:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。 

     如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的 PCB,以便进行检查。重复以上过程,直到所要进程都完成为止。   

   同时,以上操作执行完了以后,要反映出在这个操作过程中p原语和v原语操作的执行情况,于是调用预先创建的函数.并输出p,v操作在整个程序过程中的执行情况和状态.于是我们创建四个进程process1,process2,process3,process4具体反应p,v原语对四个进程的操作.要预先说明的是,在四个进程并不是与输入的四个进程一一对应.输入的四个进程要按照优先级的高低来确定它们执行的顺序,优先级从高到低顺序执行,所以创建的process1到process4四个进程函数与输入的四个进程的执行顺序是一一对应的,也就是说,优先级最高的与process1对应,依次下来.这样我们创建的四个进程函数才能正确反映p,v原语对四个具体进程的操作过程.

    过程运行中除了调用P操作申请信号量外,还要调用V操作释放信号量,V操作在释放信号量之后,还将唤醒因申请此信号量而被阻塞的过程。
    在程序运行的四个过程(PROCESS1,PROCESS2,PROCESS3,PROCESS4),其中过程运行中通过P操作申请信号量1,过程2通过V操作释放信号量2,然后做一次操作申请信号量2。四个过程的运行通过进程调度模块同意安排,调度模块通过FIND()函数找到第一个就绪过程,如果当前没有过程已在运行,就直接运行此过程,如果有,则比较两者的优先数,然后运行优先权高者。

七.系统功能

    因为没有设计动化效果,所以没有对系统功能详细说明.只是输出/输入语句.

八.数据结构

      进程控制块1PCB
     struct{
                 int id;
                 char status;
                int priority;
                int waiter1;
                }pcb[5];
    信号量
    struct{
                int value;
                int waiter2;
     }sem[4];
     现场保护栈stack
     char stack[11][4]
   每个进程都有一个大小为10个字的现场保护栈,用来保护被中断时的断点地址等信息。
    全局变量
       int i;    用以模拟一个通用寄存器
       char addr;  用以模拟程序计数器
       int m1,m2;为系统设置的公用数据被三个进程共享使用

定义进程控制块2PCB
struct pcb {

            char name[10];

            char state;

            int super;

            int ntime;

            int rtime;

            struct pcb* link;

            }*ready=NULL,*p;

现场保护栈:
       char stack[11][5]
          每个进程都有一个大小为11个字的现场保护栈,用来保护被中断时的断点地址等信息.
 全局变量
     int i;   用以模拟一个通用寄存器
     char addr;  用以模拟程序计数器
   int m1,m2;为系统设置的公用数据被四个进程共享使用.
   int num;确定进程数量

 

 struct{
       int id;   //
进程标号
       int waiter1;   //指针,用于标识等待队列的下一个进程
     int priority;  //进程优先级
     char status;  //进程状态
   }Pcb[5];进程控制快Pcb

 九.分工情况
          在我们小组合作的过程中,由我们三个人共同完成,具体的分工是这样的:
    框图设计和编写程序代码由许向前和申友明共同完成,因为框图和程序紧密相连.
    整个幻灯片设计是由杨毅完成

十.讨论情况

       第一次讨论
   时间:2005 11 1      地点:12栋116寝室
   主持:申友明
   内容:讨论这次作业的合作和分工情况,并认真阅读老师给的辅助资料.
第二次讨论
   时间:2005 11 10     地点:12栋116寝室

   主持:杨毅
   内容:一起参阅了一些相关的资料和源代码,并构建整个作业的大约流程图.
第三次讨论
    时间:2005 11 17    地点:12栋116寝室

    主持:许向前
    内容:具体完成了分工操作,并将我们完成的部分集中在一起,反复修改,由杨毅负责的整个课件基本形成.
最后一次讨论是在
    对我们所努力产生的成果从总体上进行包装.作业完成.

十一.流程图
      流程图一.

操作系统进程调度实验报告

流程图二.

           

流程图三

流程图四      

流程图五    

流程图六   

流程图七     

  

流程图八   

流程图九

 

流程图十

  操作系统进程调度实验报告

十一.程序代码

#include

#include "iostream.h"

#include

#define num 4

#include

#define getpch(type) (type*)malloc(sizeof(type))

#define NULL 0

int m1;  //共享变量

int m2;  //共享变量

struct{

       int id;   //进程标号

       int waiter1;   //指针,用于标识等待队列的下一个进程

     int priority;  //进程优先级

     char status;  //进程状态

   }Pcb[5];

struct{

       int value;  //信号量的值

     int waiter2; //指针,用于标识等待此信号量队列的第一个进程

   }sem[4];

char stack[11][5];  //现场保护堆栈

int i;  //cpu中的通用寄存器

int ep; //当前运行进程指针

char addr;  //程序运行时的地址

void init();  //初始化

int find();  //找出就绪进程

int w2();  //

int process1();  //进程1

int process2();  //进程2

int process3();  //进程3

int process4();  //进程4

int P(int,int ,char);   //P原语

int V(int,int ,char);  //V原语

   //**************************************************

struct pcb { /* 定义进程控制块PCB */

  

   char name[10];

    char state;//状态

    int super;//最先判别优先级

    int waittime;//等待时间

    int xtime;

    int ntime;

    int rtime;

    struct pcb* link;

}*ready=NULL,*p,*t=NULL;

typedef struct pcb PCB;

 

 

   //*************************************

  

void init()  //初始化进程

{

   int j,k; 

    Pcb[0].status='w';  //进程状态设置为等待

   Pcb[0].priority=5;  //进程的优先级别

   for(j=1;j<=4;j++)

   {

     Pcb[j].id=j;  //进程编号

     Pcb[j].status='r';    //进程状态设置为就绪

     Pcb[j].waiter1=0;  //进程指针初始化为0

     Pcb[j].priority=j;  //设置进程优先级

   }

   for(j=1;j<=3;j++)

   {

     sem[j].value=1;  //信号量赋值为1

     sem[j].waiter2=0;  //等待信号量队列的初始化

   }

  

  

    i=0;  //CPU通用寄存器初始化

    ep=0;  //

    addr='0';  //程序运行地址

    m1=0;  //共享变量初始化

    m2=0;  //共享变量初始化\

    for(j=1;j<=10;j++)

   {

     for(k=1;k<=4;k++)

       

          stack[j][k]='0';  //现场保护堆栈初始化

   }

}

  

  

int find()

{  //查找初始化变量

   int j;

    

   for(j=1;j<=4;j++)

   if(Pcb[j].status=='r')

     return(j); //如果pcb队列中有就绪进程,返回进程编号

   return(0);

}

  

int w2()

{  //进程调度程序

   int pd;

   pd=find();  //找出就绪进程编号

   if(pd==0)

     return(0); //如果没有找到就绪进程,退出程序

     else if(ep==0)

     {    //如果当前运行进程是否为0

         Pcb[pd].status='e';   //直接将当前进程设置为运行状态

        ep=pd;  //当前运行进程设置为pd

        printf("进程%d正在执行\n",ep);

     }

     else

   if(Pcb[pd].priority如果当前进程比待调入进程优先级进行比较

   {//调入进程优先级别高

        Pcb[ep].status='r'; //把CPU运行进程执行状态设置为就绪

        printf("读取进程%d\n",Pcb[pd].id);

        Pcb[pd].status='e'; //将待调入进程执行状态设置为执行

        ep=pd; //将当前运行进程指针为待调入进程

   }

  

   printf("运行进程%d\n",ep);

   i=stack[1][ep];  //恢复进程的通用寄存器中的值和运行地址。

   addr=stack[2][ep];

   switch(ep)

   { //根据当前运行的进程选择运行

   case 1:process1();

           break;

   case 2:process2();

           break;

    case 3:process3();

           break;

    case 4:process4();

           break;

   default:printf("当前进程出现错误%d\n",ep);

           break;

   }

}

  

  

int process1()

{//进程1

   if(addr=='m')

     goto m; //如果当前运行地址是m,跳到m运行

     i=1;

   a:

     printf("进程1在信号量sem[1]上调用P操作\n");

     if(P(1,1,'m')==0) return(0); //进行p操作,m表示程序执行到m

     else goto m;

   m:

     printf("打印进程1...m1=%d\n",m1); //进程1的操作,打印,寄存器i+5

     printf("打印进程1...i=%d\n",i);

     i+=5;

  

     goto a; //跳回a执行

   }

  

   int process2()

   {//进程分为4部分

      if(addr=='m') goto m;

      if(addr=='n') goto n;

      i=1;

  

   a:

      printf("进程2在信号量sem[2]上调用P操作\n");

      if(P(2,2,'m')==0) return(0);

  

   m:

      m1=2*m2;

      printf("进程2在信号量sem[1]上调用V操作m1=%d\n",m1);

      if(V(1,2,'n')==0) return(0);

      else{

     

   n:

        printf("打印进程2...i=%d\n",i);

        i+=10;

        goto a;

      }

   }

  

   int process3()

   {

      if(addr=='m') goto m;

      if(addr=='n') goto n;

      i=1;

   a:

      //if(i>4){

      printf("进程3在信号量sem[3]上调用P操作\n");

      if(P(3,3,'m')==0) return(0);

     // }

   m:

      m1=3*m2;

      printf("进程3在sem[2]信号量上调用V操作m=%d\n",m2);

      if(V(2,3,'n')==0) return(0);

      else{

   n:

          printf("打印进程3...i=%d\n",i);

        i+=15;

         goto a;

      }

   }

   int process4()

   {

      if(addr=='m') goto m;

      if(addr=='n') goto n;

      i=1;

   a:

      if(i>4){

      printf("进程4在信号量sem[3]上调用P操作\n");

      if(P(3,4,'n')==0) return(0);

      }

    n:

      m2=i;

      printf("进程4在sem[3]信号量上调用V操作m=%d\n",m2);

      if(V(3,4,'m')==0) return(0);

      else{

   m:

          printf("打印进程4...i=%d\n",i);

        i+=1;

        goto a;

      }

   }

  

   int P(int se,int P,char ad)//p操作

   {

      int w;

      sem[se].value--; //信号量减1

      if(sem[se].value==0) return(1); //如果信号量=0,返回1,说明阻塞

      printf("阻塞当前进程%d\n",P);

      Pcb[P].status='w'; //改变进程状态

      ep=0; //运行进程为空

      Pcb[P].waiter1=0; //设为尾末

      w=sem[se].waiter2; //找出等待队列的队尾

      if(w==0) sem[se].waiter2=P; //插入等待队列

      else{

        while(Pcb[w].waiter1!=0) w=Pcb[w].waiter1;

        Pcb[w].waiter1=P;

      }

      stack[1][P]=i; //保存现场

      stack[2][P]=ad;

      return(0);

   }

  

   int V(int se,int P,char ad)//v操作

   {

      int w;

      sem[se].value++; //信号量加1

      if(sem[se].value>0) return(1); //信号量>0,无等待进程

      w=sem[se].waiter2; //返回第一个等待进程

      sem[se].waiter2=Pcb[w].waiter1; //调整位置

      Pcb[w].status='r'; //进程改变状态

      printf("唤醒进程%d\n",w);

      stack[1][P]=i; //进程状态进栈

      stack[2][P]=ad;

      return(0);

   }

sort() /* 建立对进程进行优先级排列函数*/

{

   PCB *first, *second;

    int insert=0;

    if((ready==NULL)||((p->super)>(ready->super)))

       /*优先级最大者,插入队首*/

   {

     p->link=ready;

        ready=p;

   }

   else /* 进程比较优先级,插入适当的位置中*/

   {

     first=ready;

        second=first->link;

        while(second!=NULL)

     {

        if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/

        { /*插入到当前进程前面*/

               p->link=second;

               first->link=p;

               second=NULL;

               insert=1;

        }

        else /* 插入进程优先数最低,则插入到队尾*/

        {

                first=first->link;

                 second=second->link;

        }

     }

          if(insert==0)

          first->link=p;

   }

}

sort1()

{

   p->link=t;

    ready=p;

}

input() /* 建立进程控制块函数*/

{

    int i;

    //clrscr(); /*清屏*/

    //printf("\n 请输入进程号:");

    //scanf("%d",&num);

    for(i=0;i

   {

     printf("\n 进程号No.%d:\n",i);

        p=getpch(PCB);

        printf("\n 输入进程名(字符/字符串):");

        scanf("%s",p->name);

        printf("\n 输入进程优先数:");

       scanf("%d",&p->super);

        printf("\n阻塞进程的时间片 :");

       scanf("%d",&p->waittime);

       printf("\n 进程要运行的时间:");

       scanf("%d",&p->ntime);

       printf("\n阻塞时间:");

       scanf("%d",&p->xtime);

       printf("\n");

       p->rtime=0;

       p->state='w';

       p->link=NULL;

       sort(); /* 调用sort函数*/

   }

}

int space()

{

   int l=0;

   PCB* pr=ready;

    while(pr!=NULL)

   {

     l++;

        pr=pr->link;

   }

   return(l);

}

disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/

{

   printf("\n qname \t state \t waittime \t ndtime \t runtime \t xtime\n");

    printf("%s\t",pr->name); printf("    ");

    printf("%c\t",pr->state); printf("      ");

     printf("%d\t",pr->waittime);printf("           ");

    printf("%d\t",pr->xtime); printf("              ");

    printf("%d\t",pr->ntime); printf("            ");

    printf("%d\t",pr->rtime);printf("                ");

    printf("\n");

}

check() /* 建立进程查看函数 */

{

   PCB* pr;

    PCB* pp;

    printf("\n**********当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/

     disp(p);

    pr=ready;

    printf("\n***********当前就绪队列状态为:\n"); /*显示就绪队列状态*/

    while(pr!=NULL)

   {

         disp(pr);

         pr=pr->link;

   }

        pp=t;

         printf("\n阻塞队列状态为:\n");

        while(pp!=NULL)

     {

           disp(pp);

           pp=pp->link;

           disp(pr);

            pr=pr->link;

     }

}

destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/

{

   printf("\n 进程 [%s] 已完成.\n",p->name);

    free(p);

}

running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/

{

   PCB *ptr;

    while(p->rtime!=p->ntime)

   {

     p->rtime++;

        printf("\n当前所运行的进程状态为:");

        disp(p);

        ptr=t;

        while(ptr!=NULL)

     {

        ptr->xtime--;

            if(ptr->xtime==0)

        {

          p=ptr;

                sort();

        }

       ptr->link=ptr;

     }

       if(p->rtime==p->waittime)

      {

        printf("\n该进程被阻塞:");

            sort1();

           break;}

   }

    if(p->rtime==p->ntime)

     destroy();

}

//**

main() 

{

     //******************************************

   int len,h=0;

    char ch;

    cout<<"输入四个进程的相关数据:"<

    cout<<"***************************************************************"<

    input(); //函数调用

     len=space();

    printf("%d",len);

     while((len!=0)&&(ready!=NULL))

    {

      ch=getchar();

         h++;

         printf("\n The execute number:%d \n",h);

         p=ready;

         ready=p->link;

         p->link=NULL;

         p->state='R';

         check();

        running();

       printf("\n  ");

       printf("\n 按任一键继续......");

       ch=getchar();

    }

     printf("\n\n 进程已经完成.\n");

     cout<<"******************************************************"<

     ch=getchar();

   //*****************************************************

   init(); //调用该函数

   cout<<"现在输出四个进程的p,v操作的具体执行情况"<

   cout<<"**********************************************"<

    printf("系统程序开始执行\n");

   for(;;)

   {

        if(find()!=0) //找出就绪进程

           w2();  //进程调度

        else break;//退出程序

   }

     printf("系统程序结束\n");

     cout<<"***********************************************"<

     cout<<"冰☆☆snow小组设计"<

}

    

//**************

运行示列

十三.实验小结

操作系统是计算机系统中必不可少的系统软件。它是计算机系统中各种资源的管理者和各种活动的组织者、指挥者。操作系统采用时间片法调度进程,使系统资源得到充分的利用,用户也可以花更少的时间完成更多的工作,这次模拟系统调度进程,让我们明白了系统时间片的调度方法和p,v原语操作情况,对操作系统理论的学习更加深一层.同时,这是我们小组共同努力的结果,团体合作的精神是很可贵的.

这次作业具有深远的意义.

相关推荐