精华内容
下载资源
问答
  • 实用标准文案 优 先 级 调 度 算 法 实 验 报 告 院系 * 学院 班级 * 姓名 * 学号 * 精彩文档 实用标准文案 一实验题目 优先级调度算法 二实验目的 进程调度是处理机管理的核心内容 本实验要求用高级语言编写 模拟...
  • (一) 实验目的 进程是操作系统中最基本、最重要的概念,进程调度又是操作系统的核心模块。本实验要求学生独立地用C 或 C++语言编写一个简单的进程管理程序,其主要部分是进程调度。调度算法可由学生自行选择,如...

    (一) 实验目的

     

    进程是操作系统中最基本、最重要的概念,进程调度又是操作系统的核心模块。本实验要求学生独立地用CC++语言编写一个简单的进程管理程序,其主要部分是进程调度。调度算法可由学生自行选择,如基于动态优先级的调度算法或多级反馈队列调度算法。

     

    通过本实验可加深学生对进程各种状态的转化和各种调度算法的理解,提高系统程序设计能力。

     

    (二) 实验题目

     

    以链式结构组成空闲 PCB 栈,以双向链式结构组成进程的就绪队列和睡眠队列,模拟 UNIX 的进程管理程序,实现以下操作(可用键盘命令或由产生的随机数决定操作和参数)。

    1.创建一个新进程:如 pid=newp(pri,size,time),申请空闲PCB 和所需内存,填写 PCB

     

    的各项初始数据,将该 PCB 送入就绪队列。

     

    2.调度和执行:自己设计优先调度算法,在就绪队列中选择一个优先级最高的进程,使其运行若干个单位时间。要求在运行期间进程的p_cpup_prip_time 要变化,并在适当的时机重新调度。

     

    3.进程睡眠:进程运行时可调用自编的睡眠函数,主动进入睡眠状态,并转调度程序。也可由操作使进程强迫挂起,睡眠适当时间。进程睡眠时要在PCB 中记录睡眠原因和优先数。

     

    4.进程的唤醒:根据睡眠原因,将相应的进程从睡眠队列中调出,转入就绪队列。如该进程优先级比现运行进程优先级高,转调度程序。

     

    5.进程的终止:如一个进程运行完作业所需的时间,或者用操作杀死该进程,该进程就终止,释放所占用的内存和 PCB 资源,转调度程序。

     

    () 主要数据结构

     

    每一个进程用一个进程控制块 PCB 表示,参考的 proc 结构定义如下:

     

    struct proc {

     

     

    char

    p_pid;

    进程标识数

    char

    p_pstat;

    进程状态

    caddr_t  p_addr;

    进程图象在内存中首址

    int

    p_size;

    进程图象的长度

    char

    p_pri;

    进程优先数

    char

    p_cpu;

    进程当前运行的时间

    int

    p_time;

    作业运行的(剩余)总时间

    char

    p_wchan;

    进程睡眠原因

     

    structproc *p_next, *p_prior;      进程 proc 的双向链指针

     

    }

     

    系统中有一个全局变量 curproc 指向现运行进程,还要定义几个队列的首指针。

     

     

     

     

    (四)实验过程

    1.    实验进程调度算法:

         1)动态优先权:当前运行进程用完时间片后,其优先权减去一个常数。

         2)轮转调度:每个个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。

    2.    实验程序框图:

    1)轮询调度:

    (2)动态优先级调度

     

    3.    实验代码

    #include <iostream>

    #include <vector>

    #include <algorithm>

    #include <iomanip>

    #include <ctime>

    using namespace std;

     

    //优先权法pcb

    class PCB//类定义PCB表,适用于优先数

    {

    public:

        int ID;

        int priority;

        int CPUtime;//runnedtime

        int ALLtime;//needtime

        int State;//1ready 2runing 3finish

        int flag;//flag=1 finished

        void set_PCB(int a,int b,int c,int d, inte,int f)

        {

            ID=a;

            priority = b;

            CPUtime=c;

            ALLtime=d;

            State=e;

            flag=f;

        }

    };

    //轮转法pcb

    class PCB2

    {

    public:

        int ID;

        int CPUtime;

        int ALLtime;

        int State;

        int flag;

        void set_PCB2(int a,int b,int c,int d, inte)

        {

            ID=a;

            CPUtime=b;

            ALLtime=c;

            State=d;

            flag=e;

        }

    };

     

    boolpriority_sort_higher(const PCB &m, const PCB &n)//sort函数,定义按优先数排序,当优先数相同时按序号排序(即先进先出)/priority high idsmall

    {

        if(m.priority == n.priority) return m.ID< n.ID;

        return m.priority > n.priority;

    }

     

     

     

     

    void priority_way(vector<PCB> &pcb, vector<PCB> &wait,int pcbnum)//优先数算法

    {

        vector<PCB>::iterator it1;

        it1 = pcb.begin();

        int flag = pcbnum;

        while(flag)

        {

            wait.erase(wait.begin());

            (*it1).State = 2;

            (*it1).priority -= 3;

            (*it1).CPUtime  += 1;

            (*it1).ALLtime -= 1;

            if((*it1).ALLtime == 0)

            {

                flag -= 1;

                (*it1).flag =1;

               cout<<left<<setw(10)<<(*it1).ID<<setw(10)<<(*it1).State<<setw(10)<<(*it1).priority<<setw(10)<<(*it1).CPUtime<<setw(10)<<(*it1).ALLtime<<setw(10)<<(*it1).flag<<endl;

                pcb.erase(pcb.begin());

                sort(wait.begin(), wait.end(),priority_sort_higher);

                sort(pcb.begin(), pcb.end(),priority_sort_higher);

            }

            else

            {

               cout<<left<<setw(10)<<(*it1).ID<<setw(10)<<(*it1).State<<setw(10)<<(*it1).priority<<setw(10)<<(*it1).CPUtime<<setw(10)<<(*it1).ALLtime<<setw(10)<<(*it1).flag<<endl;

                (*it1).State = 1;

                wait.push_back(*it1);

               sort(wait.begin(),wait.end(),priority_sort_higher);

               sort(pcb.begin(),pcb.end(),priority_sort_higher);

            }

     

     

     

        }

     

    }

     

    void round_robin_way(vector<PCB2> &pcb2,vector<PCB2> &wait2)//时间片,every 2

    {

        vector<PCB2>::iterator it2;

        it2 = wait2.begin();

        int flag=5;

        while(flag)

        {

            it2 = pcb2.begin();

            wait2.erase(wait2.begin());//出队(等待队列)

            (*it2).State = 2;

            if((*it2).ALLtime==1)

            {

                (*it2).CPUtime +=1;

                (*it2).ALLtime -=1;

                flag -= 1;

                (*it2).flag = 1;

                cout << left <<setw(10) << (*it2).ID << setw(10) <<(*it2).State<<setw(10)<<(*it2).CPUtime<<setw(10)<<(*it2).ALLtime<<setw(10)<<(*it2).flag<<endl;

                pcb2.erase(pcb2.begin());

                continue;

            }

            else if((*it2).ALLtime==2)

            {

                (*it2).CPUtime +=2;

                (*it2).ALLtime -=2;

                flag-=1;

                (*it2).flag =1;

               cout<<left<<setw(10)<<(*it2).ID<<setw(10)<<(*it2).State<<setw(10)<<(*it2).CPUtime<<setw(10)<<(*it2).ALLtime<<setw(10)<<(*it2).flag<<endl;

                pcb2.erase(pcb2.begin());

                continue;

            }

            else

            {

                (*it2).State = 2;

                (*it2).CPUtime +=2;

                (*it2).ALLtime -=2;

                cout<<left<<setw(10)<<(*it2).ID<<setw(10)<<(*it2).State<<setw(10)<<(*it2).CPUtime<<setw(10)<<(*it2).ALLtime<<setw(10)<<(*it2).flag<<endl;

                (*it2).State = 2;

                wait2.push_back(*it2);

                PCB2 q = *it2;

                pcb2.erase(pcb2.begin());

                pcb2.push_back(q);

            }

        }

    }

     

    int random(int start, int end)

    {

        return start+(end-start)*rand()/(RAND_MAX +1.0);

    }

     

     

    int main( )

    {

       cout<<"-------------------------------模拟进程调度----------------------------------"<<endl;

        srand(unsigned(time(0)));

        int flag_0;

        cout<<"请输入想要模拟进程调度算法的编号"<<endl;

        cout<<"1.优先数调度;2.时间片轮转调度。"<<endl;

        cin>>flag_0;

        int pcbnum=0;

        cout<<"创建进程数量:";

        cin>>pcbnum;

     

        int pro,time;

        if(flag_0 == 1)

        {

            vector<PCB> pcb;

     

            cout<<"创建"<<pcbnum<<"个进程,即将设置随机优先数与运行时间(优先数越大优先级越高)"<<endl;

     

            for( int i = 1; i <= pcbnum; i++)

            {

                pro=random(1,30);

                time=random(1,20);

                PCB q;

                q.set_PCB(i,pro,0,time,1,0);

               cout<<"id:"<<i<<""<<"priority:"<<pro<<""<<"Alltime:"<<time<<endl;

                pcb.push_back(q);

            }

           sort(pcb.begin(),pcb.end(),priority_sort_higher);//按优先数排序,利用sort函数

     

            vector<PCB> wait(pcbnum);

           copy(pcb.begin(),pcb.end(),back_inserter(wait));

            cout<<"该进程运行情况如下(flag=0代表未完成,flag=1代表已完成)"<<endl;

            cout<<left<<setw(10)<<"ID"<<setw(10)<<"State"<<setw(10)<<"priority"<<setw(10)<<"CPUtime"<<setw(10)<<"ALLtime"<<setw(10)<<"flag1" << endl;

     

            priority_way(pcb,wait,pcbnum);

        }

        else if(flag_0 ==2)

        {

            vector <PCB2> pcb2;

            vector<PCB2>::iterator it2;

            it2 = pcb2.begin();

            cout<<"创建"<<pcbnum<<"个进程,即将设置随机优先数与运行时间(优先数越大优先级越高)"<<endl;

     

            for(int i = 1; i <= 5; i++)

            {

                time=random(1,20);

                PCB2 q2;

                q2.set_PCB2(i,0,time,1,0);

               cout<<"id:"<<i<<""<<"Alltime:"<<time<<endl;

                pcb2.push_back(q2);

            }

            vector<PCB2> wait2(pcbnum);

           copy(pcb2.begin(),pcb2.end(),back_inserter(wait2));

            cout<<"该进程运行情况如下(flag=0代表未完成,flag=1代表已完成)"<<endl;

            cout <<left<<setw(10)<<"ID"<<setw(10)<<"State"<<setw(10)<<"CPUtime"<<setw(10)<<"ALLtime"<<setw(10)<<"flag1" << endl;

            round_robin_way(pcb2, wait2);

        }

     

       cout<<"----------------------------------END--------------------------------------"<<endl;

        return 0;

    }

     

    4.  实验结果

    (1)优先数调度:

          

     

     

     

    (2)轮询调度:



    (五)实验总结:

    通过这次实验,我采用的是两种进程调度算法对四个进程进行调度,每个进程可有三个状态,并假设初始状态为就绪状态。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的优先数或轮转时间数以及进程需运行的时间片数的初始值均由用户给定。在优先数算法中,进程每执行一次,优先数减3,CPU时间片数加1,进程还需要的时间片数减1。在轮转算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了2个单位),这时,CPU时间片数加2,进程还需要的时间片数减2,并排列到就绪队列的队尾上。 对于遇到优先数一致的情况,采用FIFO策略解决。

    通过这次实验,对进程调度有深入的了解,在实验过程中遇到了很多问题,但是通过和同学请教,以及在网上查找有关资料,最终完成了本次实验要求。  

      


    展开全文
  • 多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机,以使系统中的歌就绪进程有条不紊的运行。本实验模拟实现处理机调度,以加深对处理机调度的理解
  • 操作系统进程调度算法,循环轮转算法和优先级数算法
  • 本文件包含完整的大作业完整的资源,包含c++源代码,可运行,有调度视频,有实验报告
  • 实验报告 班级: 计算机科学与技术B191 学号: 2019537130 姓名: 陈力源 日期: 5月8日 ⒈ 实验题目 进程调度模拟实验。 2.实验要求 设计一段程序来模拟优先级调度算法和时间片轮转算法。要求可以指定...

    实验报告

     

    实验题目

    进程调度模拟实验。

    2.实验要求

    设计一段程序来模拟优先级调度算法和时间片轮转算法。要求可以指定进程的数量、各进程需要CPU的时间和各进程的优先级。

    3. 实验目的

    通过模拟进程调度算法,了解进程调度的过程并比较不同的调度算法的区别。

    实验原理分析

    ⑴进程调度算法是指处理机的分配策略。

    优先数调度算法是指对每个进程确定一个优先数,进程调度总是让具有最高优先数的进程先使用处理机。如果进程具有相同的优先数,再按先来先服务的次序分配处理机。在本实例中采用动态优先数算法。

    时间片轮转算法是指就绪进程按就绪的先后次序排成队列,每次总是选择就绪队列中的第一个进程占用处理机,但规定只能使用一个“时间片”。

    ⑵系统中的进程可以用进程控制块PCB来表示,PCB的结构定义如表5-8所示:

     

    表5-8 PCB结构

    进程标识符

    char name

    进程占用CPU时间

    int cputime

    进程优先数

    int prio

    完成进程还需要的时间

    int needtime

    链指针

    struct pcb *next

     

    ⑶在进程调度时进程会交替的出现在运行、就绪和完成三种状态。可以定义三个链表来存放三种状态的进程。当进程运行时就把进程放入到运行链表中;当进程处于就绪状态时就将进程放入到就绪链表中;当进程运行完毕时就将进程放入到完成链表中。由于同一时刻运行的进程只能有一个,所以运行链表只能有一个结点。在实例程序中为了使程序更简洁忽略了进程的等待状态,仅运行了优先数调度算法,由于篇幅有限,仅显示部分结果,对于时间片轮转调度算法,请读者自行运行。

    ⑷主要变量及函数说明如表5-9所示:

     

    表5-9 主要变量及函数说明

    struct pcb

    进程控制块结构

    RUN、READY、FINSH

    运行、就绪、完成对列

    void PRINTLINK(int t)

    显示三个队列,t为运行的次数

    PCB *CPCBLINK()

    建立就绪队列

    void JXDLPX()

    将队列按优先级排序

    void YXS()

    优先数调度算法

    void SJP()

    时间片轮转算法

     

    5.实验代码清单

    #include "stdafx.h"

     

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include"stdafx.h"

    typedef struct node

    {

      char name[20];    /*进程的名字*/

      int prio;     /*进程的优先级*/

      int round;     /*分配CPU的时间片*/

      int cputime;    /*CPU执行时间*/

      int needtime;    /*进程执行所需要的时间*/

      char state;     /*进程的状态,W——就绪态,R——执行态,F——完成态*/

      int count;     /*记录执行的次数*/

      struct node *next;   /*链表指针*/

    }PCB;

    PCB *ready=NULL,*run=NULL,*finish=NULL; /*定义三个队列,就绪队列,执行队列和完成队列*/

    int num;

    void GetFirst();    /*从就绪队列取得第一个节点*/

    void Output();     /*输出队列信息*/

    void InsertPrio(PCB *in);  /*创建优先级队列,规定优先数越小,优先级越高*/

    void InsertTime(PCB *in);  /*时间片队列*/

    void InsertFinish(PCB *in);  /*时间片队列*/

    void PrioCreate();    /*优先级输入函数*/

    void TimeCreate();    /*时间片输入函数*/

    void Priority();    /*按照优先级调度*/

    void RoundRun();    /*时间片轮转调度*/

    int main(void)

    {

      char chose;

      printf("请输入要创建的进程数目:\n");

      scanf("%d",&num);

      getchar();

      printf("输入进程的调度方法:(P/R)\n");

      scanf("%c",&chose);

      switch(chose)

      {

      case 'P':

      case 'p':

        PrioCreate();

        Priority();    

        break;

      case 'R':

      case 'r':

        TimeCreate();

        RoundRun();

        break;

      default:break;

      }

      Output();

      return 0;

    }

    void GetFirst()  /*取得第一个就绪队列节点*/

    {

      run = ready;

      

      if(ready!=NULL)

      {

        run ->state = 'R';

        ready = ready ->next;

        run ->next = NULL;

      }

    }

    void Output()    /*输出队列信息*/

    {

      PCB *p;

      p = ready;

      printf("进程名 优先级  cpu时间 需要时间 进程状态 \n");

      while(p!=NULL)

      {

        printf("   %s    %d      %d        %d         %c        \n",p->name,p->prio,p->cputime,p->needtime,p->state);

        p = p->next;

      }

      p = finish;

      while(p!=NULL)

      {

        printf("   %s    %d      %d        %d         %c        \n",p->name,p->prio,p->cputime,p->needtime,p->state);

        p = p->next;

      }

      p = run;

      while(p!=NULL)

      {

        printf("   %s    %d      %d        %d         %c        \n",p->name,p->prio,p->cputime,p->needtime,p->state);

        p = p->next;

      }

    }

    void InsertPrio(PCB *in) /*创建优先级队列,规定优先数越小,优先级越低*/

    {

      PCB *fst,*nxt;

      fst = nxt = ready;

      

      if(ready == NULL)  /*如果队列为空,则为第一个元素*/

      {

        in->next = ready;

        ready = in;

      }

      else     /*查到合适的位置进行插入*/

      {

        if(in ->prio >= fst ->prio)  /*比第一个还要大,则插入到队头*/

        {

          in->next = ready;

          ready = in;

        }

        else

        {

          while(fst->next != NULL)  /*移动指针查找第一个别它小的元素的位置进行插入*/

          {

            nxt = fst;

            fst = fst->next;

          }

          

          if(fst ->next == NULL) /*已经搜索到队尾,则其优先级数最小,将其插入到队尾即可*/

          {

            in ->next = fst ->next;

            fst ->next = in;

          }

          else     /*插入到队列中*/

          {

            nxt = in;

            in ->next = fst;

          }

        }

      }

    }

    void InsertTime(PCB *in)  /*将进程插入到就绪队列尾部*/

    {

      PCB *fst;

      fst = ready;

      

      if(ready == NULL)

      {

        in->next = ready;

        ready = in;

      }

      else

      {

        while(fst->next != NULL)

        {

          fst = fst->next;

        }

        in ->next = fst ->next;

        fst ->next = in;

      }

    }

    void InsertFinish(PCB *in)  /*将进程插入到完成队列尾部*/

    {

      PCB *fst;

      fst = finish;

      

      if(finish == NULL)

      {

        in->next = finish;

        finish = in;

      }

      else

      {

        while(fst->next != NULL)

        {

          fst = fst->next;

        }

        in ->next = fst ->next;

        fst ->next = in;

      }

    }

    void PrioCreate() /*优先级调度输入函数*/

    {

      PCB *tmp;

      int i;

      

      printf("输入进程名字和进程所需时间以及优先权:\n");

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

      {

        if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL)

        {

          perror("malloc");

          exit(1);

        }

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

        getchar();    /*吸收回车符号*/

        scanf("%d",&(tmp->needtime));

           getchar();    /*吸收回车符号*/

           scanf("%d",&(tmp ->prio));

        tmp ->cputime = 0;

        tmp ->state ='W';

        tmp ->round = 0;

        tmp ->count = 0;

        InsertPrio(tmp);      /*按照优先级从高到低,插入到就绪队列*/

      }

    }

    void TimeCreate() /*时间片输入函数*/

    {

      PCB *tmp;

      int i;

      

      printf("输入进程名字和进程时间片所需时间:\n");

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

      {

        if((tmp = (PCB *)malloc(sizeof(PCB)))==NULL)

        {

          perror("malloc");

          exit(1);

        }

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

        getchar();

        scanf("%d",&(tmp->needtime));

        tmp ->cputime = 0;

        tmp ->state ='W';

        tmp ->prio = 0;

        tmp ->round = 2;  /*假设每个进程所分配的时间片是2*/

        tmp ->count = 0;

        InsertTime(tmp);

      }

    }

    void Priority()   /*按照优先级调度,每次执行一个时间片*/

    {

      int flag = 1;

      

      GetFirst();

      while(run != NULL)  /*当就绪队列不为空时,则调度进程如执行队列执行*/

      {

        Output();  /*输出每次调度过程中各个节点的状态*/

        while(flag)

        {

          run->cputime++; /*CPU时间片加一*/

          run->needtime--;/*进程执行完成的剩余时间减一*/

          if(run->needtime == 0)/*如果进程执行完毕,将进程状态置为F,将其插入到完成队列*/

          {

            run ->state = 'F';

            run->count++; /*进程执行的次数加一*/

            InsertFinish(run);

            flag = 0;

          }

          else   /*将进程状态置为W,入就绪队列*/

          {

            run->state = 'W';

            run->count++; /*进程执行的次数加一*/

            InsertTime(run);

            flag = 0;

          }

        }

        flag = 1;

        GetFirst();    /*继续取就绪队列队头进程进入执行队列*/

      }

    }

    void RoundRun()    /*时间片轮转调度算法*/

    {

      

      int flag = 1;

      

      GetFirst();

      while(run != NULL)

      {

        Output();

        while(flag)

        {

          run->count++;

          run->cputime++;

          run->needtime--;

          if(run->needtime == 0) /*进程执行完毕*/

          {

            run ->state = 'F';

            InsertFinish(run);

            flag = 0;

          }

          else if(run->count == run->round)/*时间片用完*/

          {

            run->state = 'W';

            run->count = 0;   /*计数器清零,为下次做准备*/

            InsertTime(run);

            flag = 0;

          }

        }

        flag = 1;

        GetFirst();

      }

    }

    优先级调度

     

     

     

     

    时间片轮转

     

    展开全文
  • 目录 一、实验目的 二、实验内容 三、实验原理 四....六....七.... 本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。 二、实验内容 设计一个程序,根据不同的调度算...

    目录

     

    一、实验目的

    二、实验内容

    三、实验原理

    四.算法流程图

     六.运行结果

    七.实验小结


    一、实验目的

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

    二、实验内容

    1. 设计一个程序,根据不同的调度算法模拟操作系统对进程的调度。 
    2. 动态优先级法 
    3. 设计进程控制块PBC表结构,分别适用优先数调度算法 
    4.  PBC结构通常包括以下信息:进程名、进程优先数、轮转时间片、进程的CPU时间,进程状态等。根据调度算法不同,PCB结构可作适当的调整。 
    5.  建立进程队列。对不同的算法编制不同的入链程序。 
    6. 程序要求达到的运行效果:在设置好进程数量、调度算法后,系统能按设定的参数运行,并在屏幕上交替显示就绪队列和完成队列的进程名等信息。

    三、实验原理

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

    •  假定系统有五个进程每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:

    进程名

    指针

    要求运行时间

    优先数

    状态

    其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。

    指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。

    要求运行时间——假设进程需要运行的单位时间数。

    优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。

    状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。

    •  在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
    • 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例:

      队首标志

             K2    

    K1

    P1

     K2

    P2

     K3

    P3

     K4

    P4

     K5

    P5

     

    0

     

    K4

     

    K5

     

    K3

     

    K1

     

    2

     

    3

     

    1

     

    2

     

    4

     

    1

     

    5

     

    3

     

    4

     

    2

     

    R

     

    R

     

    R

     

    R

     

    R

     

    PCB1

     

    PCB2

     

    PCB3

     

    PCB4

     

    PCB5

     

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

    优先数-1

    要求运行时间-1

    来模拟进程的一次运行。

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

    • 进程运行一次后,若要求运行时间¹0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。
    • 若“就绪”状态的进程队列不为空,则重复上面(4)和(5)的步骤,直到所有进程都成为“结束”状态。
    •  在所设计的程序中应有显示或打印语句,能显示或打印每次被选中进程的进程名以及运行一次后进程队列的变化。
    • 为五个进程任意确定一组“优先数”和“要求运行时间”,启动所设计的处理器调度程序,显示或打印逐次被选中进程的进程名以及进程控制块的动态变化过程。

    四.算法流程图

    五.源程序及注释

    •  

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

        char name[10];//存储进程名
        struct pcb* next;  //指针
        int super;        //优先级数
        int ntime;       //运行时间
        int rtime;
        char state;       //进程状态
    }*ready = NULL, *p;
    typedef struct pcb PCB;  

    • 程序包含函数:

     input(); /* 建立进程控制块函数*/
    sort(); /* 建立对进程进行优先级排列函数*/  
    disp(PCB * pr) ;/*建立进程显示函数,用于显示当前进程*/
    check() ;// 建立进程查看函数 
    destroy(); /*建立进程撤消函数(进程运行结束,撤消进程)*/
    running(); /* 建立进程就绪函数(进程运行时间到,置就绪状态*/ 
     main(void) {
    }/*主函数*/
                                                               

    • 打印一份源程序并附上注释。

     

    
    #define _CRT_SECURE_NO_WARNINGS 
    #include <stdio.h>
    #include <stdlib.h> 
    
    #define getpch(type) (type*)malloc(sizeof(type)) 
    
    
    
    struct pcb   /* 定义进程控制块PCB */ {
    	char name[10];//存储进程名
    	struct pcb* next;  //指针
    	int super;        //优先级数
    	int ntime;       //运行时间
    	int rtime;
    	char state;       //进程状态
    }*ready = NULL, *p;
    typedef struct pcb PCB;
    
    void sort() /* 建立对进程进行优先级排列函数*/ {
    	PCB *first, *second;
    	int insert = 0;
    	if ((ready == NULL) || ((p->super) > (ready->super))) /*优先级最大者,插入队首*/
    	{
    		p->next = ready;//插入的数据作为链表头结点
    		ready = p;//头结点指针指向插入数
    	}
    
    	else /* 进程比较优先级,插入适当的位置中*/ {
    		first = ready;
    		second = first->next;
    		while (second != NULL)
    		{
    			if ((p->super) > (second->super)) /*若插入进程比当前进程优先数大,*/
    			{ /*插入到当前进程前面*/
    				p->next = second;
    				first->next = p;
    				second = NULL;
    				insert = 1;
    			}
    			else /* 插入进程优先数最低,则插入到队尾*/
    			{
    
    				first = first->next;
    				second = second->next;
    			}
    		}
    		if (insert == 0)
    			first->next = p;
    	}
    }
    
    void input() /* 建立进程控制块函数*/
    {
    	int i, num;
    	printf("\n 请输入进程数:");
    	scanf("%d", &num);
    	for (i = 0; i < num; i++)
    	{
    		printf("\n 进程号%d:\n", i + 1);
    		p = getpch(PCB);
    		printf("\n 输入进程名:");
    		scanf("%s", p->name);
    		printf("\n 输入进程优先数:");
    		scanf("%d", &p->super);
    		printf("\n 输入进程运行时间:");
    		scanf("%d", &p->ntime);
    		printf("\n");
    		p->rtime = 0; p->state = 'w';
    		p->next = NULL;
    		sort(); //调用sort函数
    	}
    }
    
    int space()
    {
    
    	int len = 0; PCB* pr = ready;
    	while (pr != NULL)
    	{
    		len++;
    		pr = pr->next;
    	}
    	return(len);
    }
    
    void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
    {
    	printf("\n qname \t state \t super \t ndtime   runtime \n");
    	printf("|%s\t", pr->name);
    	printf("|%c\t", pr->state);
    	printf("|%d\t", pr->super);
    	printf("|%d\t", pr->ntime);
    	printf("|%d\t", pr->rtime);
    	printf("\n");
    
    }
    
    void check() // 建立进程查看函数 
    {
    	PCB* pr;
    	printf("\n **** 当前正在运行的进程是:%s", p->name); //显示当前运行进程
    	disp(p);
    	pr = ready;
    	printf("\n ****当前就绪队列状态为:\n"); //显示就绪队列状态
    	while (pr != NULL)
    	{
    		disp(pr);
    		pr = pr->next;
    	}
    }
    
    void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
    {
    	printf("\n 进程 [%s] 已完成.\n", p->name);
    	free(p);
    }
    
    void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态*/
    
    {
    	(p->rtime)++;
    	if (p->rtime == p->ntime)
    		destroy(); /* 调用destroy函数*/
    	else
    	{
    		(p->super)--;
    		p->state = 'w';
    		sort(); /*调用sort函数*/
    	}
    }
    int main(void) /*主函数*/
    {
    	while (true)
    	{
    		int len;//
    		char ch;
    		input();
    		len =space();
    		while ((len != 0) && (ready != NULL))
    		{
    			ch = getchar();
    			p = ready;
    			ready = p->next;
    			p->next = NULL;
    			p->state = 'R';
    			check();
    			running();
    			system("pause");
    		}
    
    		printf("\n\n 进程已经完成.\n");
    	}
    	system("pause");
    	return 0;
    }
    

     六.运行结果

     

    七.实验小结

    1.基本思想:为每个进程设置一个优先级,在调度的时候,选取优先级最大的任务去执行。

    2.优先级可以是静态赋予:创建任务的时候,就指定优先级大小,并且保持不变,直到任务结束。

    3.也可以是动态赋予:优先级在执行任务中动态改变。

    4.为了防止高优先级进程无休止地运行下去,调度程序可以在每个时钟中断降低当前进程的优先级。

    5.在平时中,我们可以把不同的任务划分为不同的优先级,然后在相同优先级的任务中使用时间片轮转。

     

    展开全文
  • 一、实验名称 进程调度的设计与实现 二、实验目的 1、 综合应用下列知识点设计并...在上机实现该程序之后,要求写出实验报告,其中包括实验名称、实验目的、实验内容、程序的主要流程图、实验心得和主要源程序清单等。
  • 进程调度的设计与实现中文摘要无论是在批处理系统还是分时系统中,用户进程数一般都...关键词进程调度 C++ 优先级 生命周期 pid status前言实验目的1、综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布...

    进程调度的设计与实现

    源码下载:进程调度的设计与实现

    中文摘要

           无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。

    关键词

    进程调度 C++ 优先级 生命周期 pid status

    前言

    实验目的

    1、综合应用下列知识点设计并实现操作系统的进程调度:邻接表,布尔数组,非阻塞输入,图形用户界面GUI,进程控制块,进程状态转换,多级反馈队列进程调度算法。

    2、加深理解操作系统进程调度的过程。

    3、加深理解多级反馈队列进程调度算法。

    实验内容与主要设计思想

     

    1、采用一种熟悉的语言,如 C、 PASCAL 或 C++等,编制程序,最好关键代码采用 C/C++,界面设计可采用其它自己喜欢的语言。

    2、采用多级反馈队列调度算法进行进程调度。

    3、每个进程对应一个 PCB。在 PCB 中包括进程标识符 pid、进程的状态标识 status、进程优先级 priority、进程的队列指针 next 和表示进程生命周期的数据项 life(在实际系统中不包括该项)。

    4、创建进程时即创建一个 PCB,各个进程的 pid 都是唯一的, pid 是在 1到 100 范围内的一个整数。可以创建一个下标为 1 到 100 的布尔数组,“真”表示下标对应的进程标识号是空闲的,“假”表示下标对应的进程标识号已分配给某个进程。

    5、进程状态 status 的取值为“就绪 ready”或“运行 run”,刚创建时,状态为“ ready”。被进程调度程序选中后变为“ run”。

    6、进程优先级 priority 是 0 到 49 范围内的一个随机整数。

    7、进程生命周期 life 是 1 到 5 范围内的一个随机整数。

    8、初始化时,创建一个邻接表,包含 50 个就绪队列,各就绪队列的进程优先级 priority 分别是 0 到 49。

    9、为了模拟用户动态提交任务的过程,要求动态创建进程。进入进程调度循环后,每次按 ctrl+f即动态创建一个进程,然后将该PCB 插入就绪队列中。按 ctrl+q 退出进程调度循环。

    10、在进程调度循环中,每次选择优先级最大的就绪进程来执行。将其状态从就绪变为运行,通过延时一段时间来模拟该进程执行一个时间片的过程,然后优先级减半,生命周期减一。设计图形用户界面 GUI,在窗口中显示该进程和其他所有进程的 PCB 内容。如果将该运行进程的生命周期不为 0,则重新把它变为就绪状态,插入就绪队列中;否则该进程执行完成,撤消其 PCB。以上为一次进程调度循环。

    流程图

     

    实验实现

    实验平台

     

    硬件:

        CPU:Intel Core i5-8250u

        GPU:Intel hd graphics 620

        RAM:ddr4 8g

        SSD:Sansung pm961 256g

    软件:

        OS:deepin 15.5

        IDE:Qt 5.8.0

    主要功能模块分析

    创建进程

    void PCB_adjlist::ctreat_pcb() {   //根据指令创建进程
        PCB *newpcb=new PCB;
        newpcb->priority = qrand()%50;  //优先级0-49
        newpcb->life = qrand()%5+1;     //生命周期1-5
        newpcb->status = true;          //就绪状态
        while (true) {
            int x = qrand()%100+1;      //进程标识符1-100
            if (judge_empty(x - 1)) {
                newpcb->pid = x;
                break;
            }
        }
        int numpri = newpcb->priority;
        PCB *p = list[numpri].next;
        if (p != NULL) {
            while (p->next != NULL) {
                p = p->next;
            }
            p->next = newpcb;   //插到队尾
        }
        else {
            list[numpri].next = newpcb;
        }
    }

    运行进程

    void PCB_adjlist::run_pcb() {   //运行pcb
        int top_pcb=-1;   //记录需最先运行的pcb指针
        for (int i = 49; i >=0; i--) {
            if (list[i].next != NULL) {
                top_pcb = i;
                break;
            }
        }
        if (top_pcb == -1)  //如果无可运行的pcb,返回
            return;
        PCB *p = list[top_pcb].next,*q;  //建立两个指针,*q用来进行删除操作
        p->status = 0;  //改为运行状态
        if (p->life == 1) {  //若生命周期为1,则运行完删除
            q = p->next;
            list[top_pcb].next = q;
            delete p;
        }
        else {
            q = p->next;
            list[top_pcb].next = q; //指向下一进程
            p->status = 1;  //就绪状态
            p->life--;
            int top_pri = p->priority;
            top_pri /= 2;   //优先级减半
            p->priority = top_pri;
            p->next = NULL;
            PCB *newpcb = list[top_pri].next;
            if (newpcb == NULL) {   //插入新优先级队列
                list[top_pri].next = p;
            }
            else {
                while (newpcb->next != NULL)
                    newpcb = newpcb->next;
                newpcb->next = p;
            }
        }
        return;
    }、

    快捷键设置

    newAction = new QAction("New PCB",this);
    this->newAction->setShortcut(tr("ctrl+f")); //快捷键
    

    定时运行

    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slotRun()));  //设置定时运行
    void MainWindow::slotStart()
    {
        timer->start(1000); //开始定时运行函数,时间间隔为1s
    }

    实验结果

    截图

    源码下载:进程调度的设计与实现

    展开全文
  • 南通大学计算机科学与技术学院 操作系统课程设计 报告书 设计题目 模拟实现进程调度中的先来先 服务算法短作业优先算法时间片轮转算法优先 级调度算法 专业班级 计XXX 学生姓名 XXXXX 学 号 161xxxxxxxx 日 期 2018....
  • 题 目: 进程调度模拟设计——优先级法、最高响应比优先调度算法 初始条件: 1.预备内容:阅读操作系统的处理机管理章节内容,对进程调度的功能以及进程调度算法有深入的理解。 2.实践准备:掌握一种计算机高级...
  • 操作系统原理实验—进程调度实验报告一、目的与要求(1)进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验选用XX语言编写了一个进程调度模拟程序,使用优先级或时间的轮转法实现进程调度。...
  • 实验报告——Nachos 进程管理与调度

    千次阅读 2018-07-05 10:16:52
    (2) 掌握进程调度:实现优先级调度。 2. 实验内容 运用理论课上学习的 fork、exec、waitpid / join 等系统调用的工作原理,在 Nachos 上实现进程的管理、同步与调度。主要包含以下几点: 1. 实现 fork、exec、...
  • 此程序模拟多进程并行的运行环境,由...有六种进程调度算法可供选择,分别是时间片轮转、动态优先级、最短进程优先、最短剩余时间优先、先来先服务、多级反馈队列。 本资源包括可执行文件、源代码以及电子版实验报告
  • #include #include<queue>//调用STL中的优先队列 ...//该进程优先级 char state;//该进程的状态 PCB* next;//指向下个进程的指针 void print()const//输出进程的信息 { cout; } }; ……
  • 进程调度基本框架

    2018-06-23 16:56:32
    进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度 2)按照实验题目要求独立正确地完成实验内容(编写、调试...
  • (1) 用C语言实现对N个进程采用某种进程调度算法(如先来先服务调度、时间片轮转调度、动态优先级调度)的调度。 (2) 为了清楚地观察每个进程的调度过程,程序应将每个进程的被调度情况显示出来。 (3) 分析程序...
  • 一、实验名称 进程调度的设计与实现 二、实验目的 1、 综合应用下列知识点...11、 在上机实现该程序之后,要求写出实验报告,其中包括实验名称、实验目的、实验内容、程序的主要流程图、实验心得和主要源程序清单等。
  • 实验题目: 进程调度(综合性实验实验环境: C语言编译器 实验内容: 进程调度模拟程序:假设有10个进程需要在CPU上执行,请实现:  先进先出调度算法;  基于静态优先数的调度算法; 确定这10个进程在CPU...
  • 2.3、进程调度 2 2.4、并发环境模拟 2 3.课程设计报告内容 2 3.1 流程图 2 3.2 模块函数 3 3.3函数实现如下: 3 3.4实验结果: 5 4.总结 6 参考文献 6 附录 6 无限循环进程模拟 1.课程设计的目的 1、实现模拟...
  • 操作系统实验指导书及完整代码解答。。实验一 Windows管理综合实验。。实验二 模拟进程调度中的高优先级优先调度算法。。实验三 资源分配管理。。实验四 存储器管理。。实验五 文件管理。。
  • os实验报告.doc

    2020-01-09 20:53:16
    实现以下进程调度算法: 1.先来先服务:把当前处于就绪队列之首的那个进程调度到运行状态。也就说,它只考虑进程进入就绪队列的先后,而不...4.高优先级优先:在进行多道作业时,按照优先级高的顺序执行进程调度的顺序
  • 操作系统实验报告

    2014-01-03 20:58:52
    通过优先级调度算法的模拟,加深进程概念和进程调度过程的理解。设计原理及方案:1)在Linux下用C语言编程模拟优先级程调度算法。为了清楚地观察每个进程的调度过程,程序将每个时间片内的进程情况显示出来。2)进程...
  • WORD格式 专业资料整理 操作系统实验报告 院系 专业 班级 学号 姓名 指导老师 进程调度的模拟与内存管理 一 实验目的 在采用多道程序设计的系统中 往往有若干个进程同时处于就绪状态 当 就续进程个数大于处理器数时 ...
  • 操作系统实验报告 院系 专业 班级 学号 姓名 指导老师 进程调度的模拟与内存管理 一 实验目的 在采用多道程序设计的系统中 往往有若干个进程同时处于就绪状态 当 就续进程个数大于处理器数时 就必须依照某种策略来...
  • PAGE Word 资料 Linux操作系统原理与应用实验报告 一实验目的 1对理论课中学习的进程程序等的概念作进一步的理解明确进程和程序的区别 2加深理解进程并发执行的概念认识多进程并发执行的实质 3观察进程争夺资源的...
  • 操作系统实验报告 院系 专业 班级 学号 姓名 指导老师 精选文库 进程调度的模拟与内存管理 一 实验目的 在采用多道程序设计的系统中 往往有若干个进程同时处于就绪状态 当 就续进程个数大于处理器数时 就必须依照...
  • 进程调度要求使用高响应比优先的动态优先级调度算法。 2.设计五个进程{P0,P1,P2,P3,P4}共享三类资源{A,B,C}的系统,{A,B,C}的资源数量分别为10,5,7。进程可动态地申请资源和释放资源,系统按各进程的申请...
  • 要求能够设计与实现一个简单的进程与资源管理器,具有如下功能:完成进程创建、撤销和进程调度;完成多单元 (multi_unit)资源的管理;完成资源的申请和释放;完成错误检测和定时器中断功能。 图1 系统总体结构 ...
  • “Linux内核分析”实验报告8

    千次阅读 2016-04-17 13:55:04
    路过的小游侠+ 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 理解进程调度时机跟踪分析进程调度与进程切换的过程进程调度进程调度时机的分析:不同类型...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

优先级进程调度实验报告