操作系统——磁盘调度算法

实验目的:

  1. 理解磁盘访问时间
  2. 掌握常用的磁盘调度算法

实验器材:

Vscode

实验内容:

对教材中所讲述的主要的磁盘调度算法进行深入分析,设计一个程序模拟实现一批作业的调度,并计算每种算法下的平均寻道时间。  编程实现三种磁盘调度算法:

  1. 先来先服务调度算法;
  2. 最短寻道优先调度算法:
  3. 扫描(电梯调度)算法;
  4. 循环扫描调度算法;

实验步骤:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#define max 300

int num; //磁盘数

int request[100];   //请求磁盘序列

int begin;  //开始磁盘位置

int sum;    //横跨的总数

int k;      //每次横跨的磁盘数

int re[100];    //复制初始序列

int r[100];     //记录每个算法执行后序列

int n, m;

void input();

void FIFO() {   //先进先出

    sum = abs(begin - request[0]);

    printf("\n先进先出算法:\n    FIFO调度:      %3d", begin);

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

        printf(" %3d", request[i]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - request[0]));

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

        k = abs(request[i - 1] - request[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:    %3d", sum);

    printf("\n    平均寻道长度:      %.2f\n", 1.0 * sum / num);

}

int Smin(int b, int re[]) { //返回离开始磁盘b最近的磁盘下标

    int min = abs(b - re[0]);//初始化横跨磁道数

    int j = 0;

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

        if (abs(b - re[i]) < min) {

            min = abs(b - re[i]);

            j = i;

        }

    return j;

}

void SSTF() {   //最短寻道算法

    int c = 0, b = begin;

    printf("\n最短服务时间优先算法:\n    SSTF调度:      %3d", begin);

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

        c = Smin(b, re); //返回最近的磁道下标

        b = re[c]; //将最近的磁盘作为开始

        re[c] = 9999999; //将已经访问过的磁盘 设为很大值

        printf(" %3d", b);

        r[i] = b;

    }

    sum = abs(begin - r[0]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - r[0]));//依次输出横跨的磁道数

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

        k = abs(r[i - 1] - r[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:    %3d", sum);

    printf("\n    平均寻道时间:      %.2f\n", 1.0 * sum / num);

}

void SCAN1() {   //扫描算法

    int c = 0, b = begin;

    for (int i = 0; i < num; i++) //SSTF时re[]已改变

        re[i] = request[i];

    printf("\n扫描算法:\n    SCAN调度:      %3d", begin);

    for (int i = 0; i < num - 1; i++) {

        for (int j = 0; j < num - i - 1; j++) {

            if (re[j] > re[j + 1]) {

                re[j] = re[j] + re[j + 1];

                re[j + 1] = re[j] - re[j + 1];

                re[j] = re[j] - re[j + 1];

            }

        }

    }

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

        if (re[i] > b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    for (int i = num - 1; i >= 0; i--)

        if (re[i] < b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    sum = abs(begin - r[0]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - r[0]));

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

        k = abs(r[i - 1] - r[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:    %3d", sum);

    printf("\n    平均寻道时间:      %.2f\n", 1.0 * sum / num);

}

void SCAN2() {   //扫描算法

    int c = 0, b = begin;

    for (int i = 0; i < num; i++) //SSTF时re[]已改变

        re[i] = request[i];

    printf("\n扫描算法:\n    SCAN调度:      %3d", begin);

    for (int i = 0; i < num - 1; i++) {

        for (int j = 0; j < num - i - 1; j++) {

            if (re[j] < re[j + 1]) {

                re[j] = re[j] + re[j + 1];

                re[j + 1] = re[j] - re[j + 1];

                re[j] = re[j] - re[j + 1];

            }

        }

    }

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

        if (re[i] < b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    for (int i = num - 1; i >= 0; i--)

        if (re[i] > b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    sum = abs(begin - r[0]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - r[0]));

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

        k = abs(r[i - 1] - r[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:    %3d", sum);

    printf("\n    平均寻道时间:      %.2f\n", 1.0 * sum / num);

}

void C_SCAN1() { //循环扫描

    int c = 0, b = begin;

    printf("\n循环扫描算法:\n    CSCAN调度:     %3d", begin);

    for (int i = 0; i < num - 1; i++) {

        for (int j = 0; j < num - i - 1; j++) {

            if (re[j] > re[j + 1]) {

                re[j] = re[j] + re[j + 1];

                re[j + 1] = re[j] - re[j + 1];

                re[j] = re[j] - re[j + 1];

            }

        }

    }

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

        if (re[i] > b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

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

        if (re[i] < b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    sum = abs(begin - r[0]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - r[0]));

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

        k = abs(r[i - 1] - r[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:   %3d", sum);

    printf("\n    平均寻道时间:     %.2f\n", 1.0 * sum / num);

}

void C_SCAN2() { //循环扫描

    int c = 0, b = begin;

    printf("\n循环扫描算法:\n    CSCAN调度:    %3d", begin);

    for (int i = 0; i < num - 1; i++) {

        for (int j = 0; j < num - i - 1; j++) {

            if (re[j] < re[j + 1]) {

                re[j] = re[j] + re[j + 1];

                re[j + 1] = re[j] - re[j + 1];

                re[j] = re[j] - re[j + 1];

            }

        }

    }

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

        if (re[i] < b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

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

        if (re[i] > b) {

            printf(" %3d", re[i]);

            r[c++] = re[i];

        }

    sum = abs(begin - r[0]);

    printf("\n    横跨磁道数为:      %3d", abs(begin - r[0]));

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

        k = abs(r[i - 1] - r[i]);

        printf(" %3d", k);

        sum += k;

    }

    printf("\n    横跨的总磁道数:   %3d", sum);

    printf("\n    平均寻道时间:    %.2f\n", 1.0 * sum / num);

}

void choose_algorithm() {

    printf("             ******************\n             *磁盘调度模拟实现*\n");

    printf("             ******************\n\n\n");

    printf("             *****************************************\n");

    printf("             *****************************************\n");

    printf("             ********1、先来先服务(FCFS)算法********\n");

    printf("             ********2、最短寻道时间(SSTF)算法******\n");

    printf("         ********3、扫描(SCAN)算法**************\n");

    printf("         ********4、循环扫描(C_SCAN)算法********\n");

    printf("         ********0、退出**************************\n");

    printf("             *****************************************\n");

    printf("             *****************************************\n\n\n");

    printf("请选择磁盘调度算法:    ");

    scanf("%d", &n);

    if (n == 1) {

        input();

        FIFO();

        system("pause");

        system("cls");

        choose_algorithm();

    } else if (n == 2) {

        input();

        SSTF();

        system("pause");

        system("cls");

        choose_algorithm();

    } else if (n == 3) {

        input();

        printf("1、由小到大 \n2、由大到小\n请选择磁头移动的方向:");

        scanf("%d", &m);

        if (m == 1) {

            SCAN1();

            system("pause");

            system("cls");

            choose_algorithm();

        } else if (m == 2) {

            SCAN2();

            system("pause");

            system("cls");

            choose_algorithm();

        } else {

            printf("输入操作编号错误,请输入有效操作编号!");

            system("pause");

            system("cls");

            choose_algorithm();

        }

    } else if (n == 4) {

        input();

        printf("1、由小到大 \n2、由大到小\n请选择磁头移动的方向:");

        scanf("%d", &m);

        if (m == 1) {

            C_SCAN1();

            system("pause");

            system("cls");

            choose_algorithm();

        } else if (m == 2) {

            C_SCAN2();

            system("pause");

            system("cls");

            choose_algorithm();

        } else {

            printf("输入操作编号错误,请输入有效操作编号!");

            system("pause");

            system("cls");

            choose_algorithm();

        }

    } else if (n == 0) {

        exit(0);

    } else {

        printf("输入操作编号错误,请输入有效操作编号!");

        system("pause");

        system("cls");

        choose_algorithm();

    }

}

void input() {

    printf("请输入调度磁道数量:    ");

    scanf("%d", &num);

    printf("请输入磁道调度序列:    ");

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

        scanf("%d", &request[i]);

        re[i] = request[i];

    }

    printf("请输入当前磁道号:     ");

    scanf("%d", &begin);

    return;

}

int main() {

    choose_algorithm();

    return 0;

}

实验结果(附数据和图表):

实验结果分析及结论:

完成了对先来先服务调度算法;最短寻道优先调度算法:扫描(电梯调度)算法的实现对于代码的逻辑以及几种算法的思想有了进一步的了解,对于一些细节方面的问题应该注意,fcfs在这三种算法中较为公平,但时间较长,其余几种可能会引起饥饿,但时间较短。

实验心得体会和建议:

对知识点有了更进一步的理解,同时对于一些算法的思想进一步认识,出现的一些问题也积极和别人商量,对不懂的问题与别人交流沟通,对整体的逻辑及核心思想有了深层次的体会,几种算法的优缺点及差异有较为明显的体现,对于三种算法的体会深刻,应继续学习对知识体系继续完善,补充不足之处。总之,这些磁盘调度算法各自有不同的特点和优缺点。在实际应用中,需要根据具体场景和需求选择合适的磁盘调度算法,以优化磁盘设备的使用效率和系统的整体性能。        

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值