操作系统实验 移动臂调度算法的模拟实现(C语言版)

一、实验目的和要求

要求了解操作系统的基本原理及基本概念,掌握实现各原理的算法,能结合实际开发工具模拟演示课程中涉及的算法,以达到深入掌握操作系统理论的目的。要求学生上机之前充分准备,给出算法的设计流程和详细代码;认真做实验,要求给出调试通过的可运行程序;认真解答思考题中的问题,记录实验中遇到的问题和解决方法;独立编写实验报告。

握操作系统的设备管理功能,熟悉移动臂调度算法,设计恰当的数据结构和算法,模拟实现移动臂调度算法。

二、实验方法与步骤(需求分析、算法设计思路、流程图等)

1.先来先服务算法

先来先服务算法中,磁盘臂是随机移动的,不考虑各I/O请求之间的相对次序和移动臂当前所处位置,特点是进程等待I/O请求的时间会很长,寻道性能较差。

简单来说,就按题目中所给的柱面依次进行到达,题目中是150,30,190,20,100,55,90,那就先去150,再绕回去30,再绕去190…等待。如图所示:

 

故移动臂移动柱面总数=(150-50)+(150-30)+(190-30)+(190-20)+(100-20)+(100-55)+(90-55)=710

2.最短查找时间优先算法

最短查找时间优先算法总是先执行查找时间最短的请求,与FCFS算法相比有较好的寻道性能。简单来说,就是先去距离近的,例如本题中,离50最近的是55,就先去55,离55最近的是30,就先去30,以此类推,如图所示:

 

故移动臂移动柱面总数=(55-50)+(55-30)+(30-20)+(90-20)+(100-90)+(150-100)+(190-150)=210

3.扫描算法

扫面柱面就是“撞到南墙才回头”,往一个方向扫柱面后,就一直往那个方向扫,直到那个方向的柱面都扫完了才往反方向扫,例如本题,50往55方向扫,55的下一步就是90,90的下一步就是100…直到190的下一步199,再往回扫。

注意,按照扫描算法规则,即使没有访问请求也须扫描到头,所以到达要求的190后还要扫到199。如图所示:

 

故移动臂移动柱面总数=(55-50)+(90-55)+(100-90)+(150-100)+(190-150)+(199-190)+(199-30)+(30-20)=328

4.电梯调度算法

电梯调度算法是扫描算法的一种改进,每次总是选择沿移动臂的移动方向最近的那个柱面,若同一个柱面上有多个请求,还需进行旋转优化。如果当前的移动方向上没有但相反方向有访问请求时,就改变移动臂的移动方向。

本例题中,电梯调度算法的图示情况如下:

 

相对于扫描算法来说,并没有扫到199,因为到达190后没有要求的柱面,所以就往相反方向扫描,就跟电梯一样,从1楼乘往18楼,如果中间楼层的人想搭电梯下楼,是要先等电梯到达18楼后再往下走。

移动臂移动柱面总数=(55-50)+(90-55)+(100-90)+(150-100)+(190-150)+(190-30)+(30-20)=310

5.循环扫描算法

循环扫描算法就更简单了,往一个方向扫描后,扫完了,直接重新从反方向的开始方向扫剩下的,如图所示:

 

移动臂移动柱面总数=(55-50)+(90-55)+(100-90)+(150-100)+(190-150)+(150-100)+(190-150)+(199-190)+(199-0)+(20-0)+(30-20)=378

三、实验原始纪录(源程序、数据结构等)

#include<iostream>

#include<cstdlib>

#include<cstdio>

#include<conio.h>

using namespace std;

struct node

{

    int dat;

    struct node* pre;

    struct node* nex;

    node(int x){pre=NULL;nex=NULL;dat=x;}

};

//插入访问请求位置为x的请求

node* Insert(node* head,int x)

{

    if(head==NULL)

        return new node(x);

    node* q=new node(x);

    node *p=head;

    while(p->nex&&p->dat<x)

    {

        p=p->nex;

    }

    //cout<<"p:"<<p->dat<<endl;

    if(p->dat>x)

    {

        q->pre=p->pre;

        q->nex=p;

        if(p->pre==NULL)

        {p->pre=q;return q;}

        p->pre->nex=q;

        p->pre=q;

    }

    else

    {

        p->nex=q;

        q->pre=p;

    }

    return head;

}

//打印请求序列

void print(node *head)

{

    node *p=head;

    while(p)

    {

        printf("%d ",p->dat);

        p=p->nex;

    }

    printf("\n");

}

node* Find(node *head,int pos,bool fx)

{

    node *p=head;

    if(fx)

       {

           while(p&&p->dat<pos) p=p->nex;

           return p;

       }

    else

       {

           while(p->nex&&p->nex->dat<=pos) p=p->nex;

           return p;

       }

}

//模拟左右移臂调度

node *shift(int *ans,int *pos,node *head,bool fx)

{

    //cout<<*pos<<' '<<*ans<<endl;

    node *p=Find(head,*pos,fx);

    //cout<<"p:"<<p->dat<<endl;

    if(p)

    {

        if(fx) *ans+=(p->dat-*pos);

        else *ans+=(*pos-p->dat);

        *pos=p->dat;

        if(p->pre==NULL)

        {

            //cout<<'a'<<endl;

            head=head->nex;

            if(head) head->pre=NULL;

            free(p);

        }

        else if(p->nex==NULL)

        {

            //cout<<'b'<<endl;

            p->pre->nex=NULL;

            free(p);

        }

        else

        {

            //cout<<'c'<<endl;

            p->pre->nex=p->nex;

            p->nex->pre=p->pre;

            free(p);

        }

    }

    else cout<<"已至边界!"<<endl;

    return head;

}

int main()

{

    int x,pos,ans=0;

    node *head=NULL;

    cout<<"输入一串访问申请,数字表示物理位置(以-1结束):"<<endl;

    while(scanf("%d",&x)&&x!=-1)

        head=Insert(head,x);

    cout<<"输入你当前的位置:";

    scanf("%d",&pos);

    cout<<"用键盘A D键模拟移臂方向,用‘+ 访问位置’来添加新的任务"<<endl;

    print(head);

    while(head)

    {

        char ch;

        ch=getch();

        if(ch=='a'||ch=='A') head=shift(&ans,&pos,head,0);

        else if(ch=='d'||ch=='D') head=shift(&ans,&pos,head,1);

        else if(ch=='+')

        {

            cout<<'+'; //好看

            scanf("%d",&x);

            head=Insert(head,x);

        }

        else cout<<"麻烦认真一点输入好吗?"<<endl;

        print(head);

    }

    cout<<"任务完成!"<<endl<<"历经长度为:"<<ans<<endl;

    return 0;

}

四、实验结果及分析(计算过程与结果、数据曲线、图表等)

如图所示,算法正如开始时的模拟图运行,从而可以确定算法的正确性

 

五、实验改进与思考

    今天我们做了操作系统实验,其主题为“移臂调度算法的模拟实现”,其主要可以分为扫描算法,最短查找时间优先算法,先来先服务算法,电梯调度算法,循环扫描算法。

     磁盘是一种高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负者繁重的输入输出任务、在多道程序设计系统中,往往同时会有若干个要求访问磁盘的输入输出请求等待处理。系统可采用一种策略,尽可能按最佳次序执行要求访问磁盘的诸输入输出请求。这就叫驱动调度,使用的算法称为驱动调度算法。移臂调度算法是驱动调度技术中的算法,目的是减少为若干I/O请求服务所需消耗的总时间,从而提高系统效率。从而降低为若干个输入输出请求服务所需的总时间,从而提高系统效率。
    通过本次实验,我加深对移臂调度算法的理解。并掌握操作系统中磁盘调度的原理及实现方法,提高了自己编程的能力,提高了综合运用专业课知识的能力。这次的实验有前几次实验的经历所以做起来更加的轻松了,但是程序仍然有很多改进的地方,资源可以更加节约,算法也还有优化的余地。这次实验也让我感觉到了算法才是程序的灵魂,没有好的算法就像巧妇难为无米之炊,即使有再好的工具和基本功没有算法和基本思想也是不可行的。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值