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

操作系统实验报告

 
 

 

 

 
      

   

 

一、实习内容

选择一个调度算法,实现处理器调度。

二、实习目的

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

三、实习题目

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

[提示]:

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

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

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

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

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

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

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

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

  队首标志

         K2   

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

优先数-1   

  要求运行时间-1

来模拟进程的一次运行。

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

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

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

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

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

四、 程序中使用的数据结构及符号说明。

程序使用JAVA语言编写,数据结构为:

    Course类

Course类中的变量:

    public String  name;    // 进程的名字。

    public int time;     // 进程所需运行时间

    public int power;  // 程序优先数(数值越大优先级越高)

public char status;   // 程序状态,R=运行(就绪),E=结束。

CX类

ArrayList<Course>线性表:存放进程信息

Input类:输入进程信息

getMax类:用来获取优先级最大的进程的信息

refreshCourse类:更新进程信息(实现优先级减1和所需运行时间减1操作)

Run类:处理器优先级调度的模拟

Text类:包含主方法的程序入口

五、流程图。

 

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

源代码

publicclass Course {

   

private String name;

privatechar status;

privateint time;

privateint power;

public String getName() {

    return name;

}

publicvoid setName(String name) {

    this.name = name;

}

publicchar getStatus() {

    return status;

}

publicvoid setStatus(char status) {

    this.status = status;

}

publicint getTime() {

    return time;

}

publicvoid setTime(int time) {

    this.time = time;

}

publicint getPower() {

    return power;

}

publicvoid setPower(int power) {

    this.power = power;

}

}

publicclass CX {

private ArrayList<Course> courses=new ArrayList<Course>();

publicvoid input(){

    System.out.println("请输入实验需要模拟的进程");

    Scanner scanner=new Scanner(System.in);

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

System.out.println("请输入进程"+i+"进程的名(string)…优先级(int)……运行时间(int)");

        Course course=new Course();

        course.setName(scanner.next());

        course.setPower(scanner.nextInt());

        course.setTime(scanner.nextInt());

        course.setStatus('R');

        courses.add(course);

    }

}

publicint getMax(List<Course>list){

    Iterator<Course>iterator=list.iterator();

    int min=0;

    int i=0;

    int k=0;

    Course course=null;

    while(iterator.hasNext()){

        course=iterator.next();

        if(course.getPower()>min){

            min=course.getPower();

            k=i;

        }

        i++;

}

    return k;

        }

publicvoid refreshCourse(Course c){

    c.setPower(c.getPower()-1);

    c.setTime(c.getTime()-1);

    }

@SuppressWarnings("unchecked")

publicvoid Run(){

    ArrayList<Course>list1=(ArrayList<Course>)courses.clone();

    int rn=1;  //第几次运行

    while(list1.size()!=0){

        int max=getMax(list1);

        int flag=0;

        Course cour=list1.get(max);

        System.out.println("……第"+rn+"次运行……现在正在运行的进程:");

        System.out.println("进程号……优先级……剩余运行时间……运行状态");

        System.out.println(cour.getName()+"……"+cour.getPower()+"……"+(cour.getTime()-1+"……"+cour.getStatus()));

        refreshCourse(cour);

        list1.set(max,cour);

        if(cour.getTime()<=0){

            System.out.println("…………进程  "+cour.getName()+"结束运行…………");

            list1.remove(max);

            flag++;

                }

        ArrayList<Course>list2=new ArrayList<Course>();

        list2=(ArrayList<Course>)list1.clone();

        if(flag==0){

            list2.remove(max);

        }

        if(list2.size()!=0){

            System.out.println("……第"+(rn++)+"次运行……等待运行的进程:");

        }

        else{

            System.out.println("…………没有等待的进程!…………");

            rn++;//运行次数也加1

        }

        while(list2.size()!=0){

            int max2=getMax(list2);

            Course cos=list2.get(max2);

            System.out.println("进程号……优先级……剩余运行时间……运行状态");

            System.out.println(cos.getName() + "…………"+cos.getPower()+"…………"+cos.getTime()+"…………W");

            list2.remove(max2);

        }

    }

}

}

publicclass test {

publicstaticvoid main(String[] args){

    CX cx=new CX();

    cx.input();

    cx.Run();

    System.out.println("……………………………………运行完毕……………………");

}

}

七、打印程序运行时的初值和运行结果  。                                            

 

 

第二篇:操作系统 进程调度

淮海工学院计算机工程学院

实验报告书

课程名:  《计算机操作系统》      

题   目:        实验1进程调度        

班   级:             ^  ^             

姓   名:             ^  ^              

 

实验1进程调度

实验目的和要求

利用高级语言模拟进程的时间片轮转调度算法,响应比高者优先调度算法。

实验环境

1.PC微机。

2.Windows 操作系统。

3.C/C++/VB开发集成环境。

实验学时

    2学时,必做实验

实验内容和步骤

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

算法设计思想:

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

其中,进程名——作为进程的标识,假设五个进程的进程名分别为Q1,Q2,Q3,Q4,Q5

指针——进程按顺序排成循环队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程的指针指出第一个进程的进程控制块首地址。

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

已运行时间——假设进程已经运行的单位时间数,初始值为“0”。

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

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

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

标志单元         K2   

(4) 处理器调度总是选择标志单元指示的进程运行。由于本实验是模拟处理器调度的功能,所以,对被选中的进程并不实际的启动运行,而是执行:

已运行时间+1

来模拟进程的一次运行,表示进程已经运行过一个单位的时间。

请注意:在实际的系统中,当一个进程被选中运行时,必须置上该进程可以运行的时间片值,以及恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行满一个时间片。在这时省去了这些工作,仅用“已运行时间+1”来表示进程已经运行满一个时间片。

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

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

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

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

实验源码

#include <iostream>

#include <cstdlib>

using namespace std;

typedef struct PNode

{

       struct PNode *next;

       char name;

       int All_Time;

       int Runed_Time;

       char state;

}* Proc;

int ProcNum;

void Init(Proc &H)

{

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

       cin>>ProcNum;

       int Num = ProcNum;

       H = new PNode;

       H->next = NULL;

       Proc p =  H;

       cout<<"总进程个数默认为"<<ProcNum<<"个,输入相应息\n\n";

       while (Num--) {

              p=p->next=new PNode;

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

              cin>>p->name>>p->All_Time>>p->Runed_Time;

              p->state='R';

              p->next=NULL;

       }

       p->next = H->next;

}

void ShowInfo(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<<"开始: \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++;

              ShowInfo(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<<"结束\n";

}

void main() {

       Proc H;

       Init(H); //初始化

       ShowInfo(H); // 显示初始状态

       SJP_Simulator(H); // 模拟时间片转法

       Proc p =H->next->next;//清理

       Proc dp = H->next;

       while(p != H->next)

       {

              delete dp;

              dp = p;

              p = p->next;

       }

       delete H;

       system("pause");

}

实验结果

实验体会

这次实验是进程调度。一个操作系统的响应速度怎么样,主要看进程调度怎么样。进程调度的算法很多,但考虑到系统资源的分配和响应的快慢,就得仔细设计算法了。这次练习了顺序执行的进程调度方法。算法比较简单,现在的操作系统也不用这种调度方法,但它让我了解到了一种早期的调度方法,加深了对操作系统进程调度的印象。

相关推荐