模拟电梯调度的算法,来对磁盘进行移臂和旋转调度

  • 实验目的与要求

本实验要求学生模拟设计一个驱动调度程序,观察驱动调度程序的动态运行过程。以此来加深对驱动调度职能的理解和掌握。

设计模拟电梯调度的算法,来对磁盘进行移臂和旋转调度。

  • 数据结构及符号说明

本节将说明设计的电梯调度算法中相关的数据结构和全局变量。

Request:作为结构体,包含4个元素,用于记录I/O请求相关信息。

        ① name:字符串,记录请求的进程名。

        ② cylinder:整形,记录访问磁盘的柱面号。

        ③ magnetic:整形,记录访问磁盘的磁道号。

        ④ record:整形,记录访问的物理记录号。

Table:Request数组,请求I/O表,记录目前所有请求磁盘访问的信息。

currentProcess:Request结构体类型,指向当前得到磁盘访问资源的进程的Request项。

tableNum:整形,记录I/O请求表内的请求记录的数目。

  • 实验截图 

 

 

 

 

  • 源代码 
#include <string>
#include <iomanip> // setw
#include <iostream>
using namespace std;
#define MAXCYLINDERNUMBER 200
#define MAXMAGNETICNUMBER 20
#define MAXRECORDNUMBER 8

struct Request
{                      //请求I/O表
    string name;       //进程名
    int cylinder = -1; //柱面号
    int magnetic = -1; //磁道号
    int record = -1;   //物理记录号
} Table[100], currentProcess;
int tableNum = 0; //请求I/O表记录数

void InitcurrentProcess() //初始化初始进程
{
    currentProcess.name = "初始进程";
    currentProcess.cylinder = 0;
    currentProcess.magnetic = 0;
currentProcess.record = 0;
    //假定表中已经存在的请求
    Table[0].name = "P1";
    Table[0].cylinder = 10;
    Table[0].magnetic = 3;
    Table[0].record = 2;
    Table[1].name = "P2";
    Table[1].cylinder = 54;
    Table[1].magnetic = 12;
    Table[1].record = 7;
    Table[2].name = "P3";
    Table[2].cylinder = 10;
    Table[2].magnetic = 15;
    Table[2].record = 1;
}

int FindNearest()
{
    int min = 8, minSub = -1; //最小距离,最小距离的编号
    int distance = 8;         //当前距离
    for (int i = 0; i < tableNum; i++)
    {
        if (Table[i].cylinder == currentProcess.cylinder)
        {
            distance = abs(Table[i].record - currentProcess.record);
            if (distance < min)
            {
                min = distance;
                minSub = i;
            }
        }
    }
    return minSub;
}

void print_io() //打印请求I/O表
{
    cout << "***************************请求I/O表**************************" << endl;
    cout << "进程名:         柱面号:         磁道号:         物理记录号:" << endl;
    for (int i = 0; i < tableNum; i++)
        cout << setfill(' ') << setw(6) << Table[i].name << setfill(' ') << setw(15) << Table[i].cylinder << setfill(' ') << setw(16) << Table[i].magnetic << setfill(' ') << setw(17) << Table[i].record << endl;
    cout << "------------------This is the dividing line.------------------" << endl;
}

void PrintProcess(bool direction)
{
    string directionStr;
    if (direction == 1)
        directionStr = "up";
    else
        directionStr = "down";
    cout << "************************选中的进程信息************************" << endl;
    cout << "进程名:         柱面号:         物理记录号:         方向:" << endl;
    cout << setfill(' ') << setw(6) << currentProcess.name << setfill(' ') << setw(15) << currentProcess.cylinder << setfill(' ') << setw(16) << currentProcess.record << setfill(' ') << setw(19) << directionStr << endl;
    cout << "------------------This is the dividing line.------------------" << endl;
}
// 遍历请求表判断是否有与当前柱面号相同的访问者
int CylinderSameJudge()
{
    for (int i = 0; i < tableNum; i++)
    {
        if (Table[i].cylinder == currentProcess.cylinder)
            return i;
    }
    return -1;
}

int CylinderGreaterMin()
{
    int difference = 200;                                   //柱面号之差
    int minrecord = 8;                                      //最小物理记录
    int minCylinder = currentProcess.cylinder + difference; //选择出的最小柱面号
    int bestProcess;                                        //选择出的最佳请求号
    for (int i = 0; i < tableNum; i++)
    {
        if (abs(Table[i].cylinder - currentProcess.cylinder) < difference && Table[i].cylinder > currentProcess.cylinder)
        {
            difference = Table[i].cylinder - currentProcess.cylinder;
            minCylinder = currentProcess.cylinder + difference;
        }
    }
    for (int i = 0; i < tableNum; i++)
    {
        if (Table[i].cylinder == minCylinder && Table[i].record < minrecord)
        {
            minrecord = Table[i].record;
            bestProcess = i;
        }
    }
    if (difference == 200) //没有比当前柱面号大的访问请求
        return -1;
    else
        return bestProcess;
}

int CylinderLessMax()
{
    int difference = 200;                                   //柱面号之差
    int minrecord = 8;                                      //最小物理记录
    int maxCylinder = currentProcess.cylinder - difference; //选择出的最大柱面号
    int bestProcess;                                        //选择出的最佳请求号
    for (int i = 0; i < tableNum; i++)
    {
        if (abs(Table[i].cylinder - currentProcess.cylinder) < difference && Table[i].cylinder < currentProcess.cylinder)
        {
            difference = abs(Table[i].cylinder - currentProcess.cylinder);
            maxCylinder = currentProcess.cylinder - difference;
        }
    }
    for (int i = 0; i < tableNum; i++)
    {
        if (Table[i].cylinder == maxCylinder && Table[i].record < minrecord)
        {
            minrecord = Table[i].record;
            bestProcess = i;
        }
    }
    if (difference == 200) //没有比当前柱面号小的访问请求
        return -1;
    else
        return bestProcess;
}

void PopProcess(int process)
{
    for (int i = process; i < tableNum; i++)
    {
        Table[i] = Table[i + 1];
    }
    tableNum--;
}

void Scan()
{
    int process;        //选择的进程号
    bool direction = 1; //方向0=out,1=in,默认移臂方向为向里移
    print_io();
    if (tableNum == 0)
    { //无等待访问者
        cout << "无等待访问者!!!" << endl;
        return;
    }
    else //有等待访问者
    {
        if (CylinderSameJudge() != -1) // 有与当前柱面号相同的访问者
        {
            process = FindNearest(); // 找到旋转距离最短的访问者
        }
        else // 没有与当前柱面号相同的访问者
        {
            if (direction == 1) // 移臂方向为向里
            {
                process = CylinderGreaterMin();
                if (process == -1) // 没有比当前柱面号大的访问请求
                {
                    direction = 0;
                    process = CylinderLessMax();
                }
            }
            else //移臂方向为向外
            {
                process = CylinderLessMax();
                if (process == -1) //没有比当前柱面号小的访问请求
                {
                    direction = 1;
                    process = CylinderGreaterMin();
                }
            }
        }
        currentProcess = Table[process];
        PrintProcess(direction);
        PopProcess(process);
    }
    return;
}

void Accept()
{
    string select;
    do
    {
        Request temp;
        cout << "输入:进程名、柱面号、磁道号、物理记录号" << endl;
        cin >> temp.name >> temp.cylinder >> temp.magnetic >> temp.record;
        if (temp.cylinder < MAXCYLINDERNUMBER && temp.magnetic < MAXMAGNETICNUMBER && temp.record < MAXRECORDNUMBER)
        {
            Table[tableNum] = temp;
            tableNum++;
            cout << "登记成功!  exit.退出   others.继续" << endl;
            cin >> select;
        }
        else
            cout << "输入错误,请重输!!!  柱面号需小于200,磁道号需小于20,物理记录号需小于8." << endl;
    } while (select != "exit");
    cout << "------------------This is the dividing line.------------------" << endl;
}

int main()
{
    float roundNumber;
    string select;
    InitcurrentProcess();                         //初始化当前位置
    for (int i = 0; Table[i].cylinder != -1; i++) //统计IO请求表中请求数目
        tableNum++;
    do
    {
        cout << "*******Simulate elevator scheduling algorithms********" << endl;
        cout << "Enter a random number in the range [0,1] !!!" << endl;
        cin >> roundNumber;
        if (roundNumber > 0.5)
            Scan();
        else
            Accept();
        getchar();
        cout << "是否继续进行电梯调度算?    exit.退出   others.继续" << endl;
        cin >> select;
    } while (select != "exit");
    return 0;
}

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I_love_hanser_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值