【无标题】磁盘调度三种算法

这篇文章描述了磁盘调度中四种常见的算法:先来先服务(FCFS)、最短寻道时间优先(SSTF)、扫描(SCAN)和循环扫描(CSCAN)。每个算法都通过示例展示了如何找到最近的磁道、计算平均寻道长度以及生成寻道序列。代码实现包括了对磁道的排序和访问标志的管理,以优化磁盘操作的效率。
摘要由CSDN通过智能技术生成

 点下赞再走❤

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>

//定义一个结构体,用于存储磁道号和访问标志
typedef struct disk{
    int track; //磁道号
    int visited; //访问标志,0表示未访问,1表示已访问
}disk;

//定义一个函数,用于找到距离当前磁头位置最近的磁道
int find_min(disk list[], int n, int cur){
    int min = INT_MAX; //最小距离,初始为最大整数
    int index = -1; //最小距离对应的磁道索引,初始为-1
    for(int i = 0; i < n; i++){
        //如果磁道未被访问,且距离小于当前最小距离
        if(list[i].visited == 0 && abs(list[i].track - cur) < min){
            min = abs(list[i].track - cur); //更新最小距离
            index = i; //更新最小距离对应的索引
        }
    }
    return index; //返回最小距离对应的索引
}

//定义一个函数,用于对磁道号进行升序排序
void sort(disk list[], int n){
    for(int i = 0; i < n - 1; i++){
        for(int j = 0; j < n - i - 1; j++){
            if(list[j].track > list[j+1].track){
                disk temp = list[j];
                list[j] = list[j+1];
                list[j+1] = temp;
            }
        }
    }
}

//定义一个函数,用于实现FCFS算法
void FCFS(disk list[], int n, int cur){
    int fcfs_seq[n][2]; //用于存储FCFS寻道序列和移动距离
    double ave_seek = 0; //用于计算平均寻道长度
    for(int i = 0; i < n; i++){
        fcfs_seq[i][0] = list[i].track; //记录寻道序列
        fcfs_seq[i][1] = abs(list[i].track - cur); //记录移动距离
        cur = list[i].track; //更新当前磁头位置
        ave_seek += fcfs_seq[i][1]; //累加移动距离
    }
    ave_seek /= n; //计算平均寻道长度

    printf("\nFCFS寻道序列:\n");
    for(int i = 0; i < n; i++){
        printf("%d %d\n", fcfs_seq[i][0], fcfs_seq[i][1]);
    }
    printf("FCFS平均寻道:%0.2lf\n", ave_seek);
}

//定义一个函数,用于实现SSTF算法
void SSTF(disk list[], int n, int cur){
    int sstf_seq[n][2]; //用于存储SSTF寻道序列和移动距离
    double ave_seek = 0; //用于计算平均寻道长度
    for(int i = 0; i < n; i++){
        int index = find_min(list, n, cur); //找到距离当前磁头位置最近的磁道索引
        sstf_seq[i][0] = list[index].track; //记录寻道序列
        sstf_seq[i][1] = abs(list[index].track - cur); //记录移动距离
        list[index].visited = 1; //将该磁道标记为已访问
        cur = list[index].track; //更新当前磁头位置
        ave_seek += sstf_seq[i][1]; //累加移动距离
    }
    ave_seek /= n; //计算平均寻道长度

    printf("\nSSTF寻道序列:\n");
    for(int i = 0; i < n; i++){
        printf("%d %d\n", sstf_seq[i][0], sstf_seq[i][1]);
    }
    printf("SSTF平均寻道:%0.2lf\n", ave_seek);
}

//定义一个函数,用于实现SCAN算法
void SCAN(disk list[], int n, int cur, int dir){
    int scan_seq[n][2]; //用于存储SCAN寻道序列和移动距离
    double ave_seek = 0; //用于计算平均寻道长度
    sort(list, n); //对磁道号进行升序排序
    int index = 0; //用于记录当前磁头位置在排序后的磁道序列中的索引
    while(index < n && list[index].track < cur){
        index++; //找到第一个大于等于当前磁头位置的磁道索引
    }
    if(dir == 0){ //如果初始移动方向为向内(向小)
        index--; //从当前索引的前一个磁道开始访问
        for(int i = 0; i < n; i++){
            scan_seq[i][0] = list[index].track; //记录寻道序列
            scan_seq[i][1] = abs(list[index].track - cur); //记录移动距离
            list[index].visited = 1; //将该磁道标记为已访问
            cur = list[index].track; //更新当前磁头位置
            ave_seek += scan_seq[i][1]; //累加移动距离
            if(index > 0 && list[index-1].visited == 0){ //如果向内还有未访问的磁道,继续向内移动
                index--;
            }else{ //否则改变移动方向,向外移动
                index++;
                dir = 1;
            }
        }
    }else{ //如果初始移动方向为向外(向大)
        for(int i = 0; i < n; i++){
            scan_seq[i][0] = list[index].track; //记录寻道序列
            scan_seq[i][1] = abs(list[index].track - cur); //记录移动距离
            list[index].visited = 1; //将该磁道标记为已访问
            cur = list[index].track; //更新当前磁头位置
            ave_seek += scan_seq[i][1]; //累加移动距离
            if(index < n - 1 && list[index+1].visited == 0){ //如果向外还有未访问的磁道,继续向外移动
                index++;
            }else{ //否则改变移动方向,向内移动
                index--;
                dir = 0;
            }
        }
    }
    ave_seek /= n; //计算平均寻道长度

    printf("\nSCAN寻道序列:\n");
    for(int i = 0; i < n; i++){
        printf("%d %d\n", scan_seq[i][0], scan_seq[i][1]);
    }
    printf("SCAN平均寻道:%0.2lf\n", ave_seek);
}

//定义一个函数,用于实现CSCAN算法
void CSCAN(disk list[], int n, int cur, int dir){
    int cscan_seq[n][2]; //用于存储CSCAN寻道序列和移动距离
    double ave_seek = 0; //用于计算平均寻道长度
    sort(list, n); //对磁道号进行升序排序
    int index = 0; //用于记录当前磁头位置在排序后的磁道序列中的索引
    while(index < n && list[index].track < cur){
        index++; //找到第一个大于等于当前磁头位置的磁道索引
    }
    if(dir == 0){ //如果初始移动方向为向内(向小)
        index--; //从当前索引的前一个磁道开始访问
        for(int i = 0; i < n; i++){
            cscan_seq[i][0] = list[index].track; //记录寻道序列
            cscan_seq[i][1] = abs(list[index].track - cur); //记录移动距离
            list[index].visited = 1; //将该磁道标记为已访问
            cur = list[index].track; //更新当前磁头位置
            ave_seek += cscan_seq[i][1]; //累加移动距离
            if(index > 0 && list[index-1].visited == 0){ //如果向内还有未访问的磁道,继续向内移动
                index--;
            }else{ //否则立即返回到最外的磁道,继续向内移动
                index = n - 1;
                cur = list[index].track;
                cscan_seq[i][1] += cur;
                ave_seek += cur;
            }
        }
    }else{ //如果初始移动方向为向外(向大)
        for(int i = 0; i < n; i++){
            cscan_seq[i][0] = list[index].track; //记录寻道序列
            cscan_seq[i][1] = abs(list[index].track - cur); //记录移动距离
            list[index].visited = 1; //将该磁道标记为已访问
            cur = list[index].track; //更新当前磁头位置
            ave_seek += cscan_seq[i][1]; //累加移动距离
            if(index < n - 1 && list[index+1].visited == 0){ //如果向外还有未访问的磁道,继续向外移动
                index++;
            }else{ //否则立即返回到最内的磁道,继续向外移动
                index = 0;
                cur = list[index].track;
                cscan_seq[i][1] += cur;
                ave_seek += cur;
            }
        }
    }
    ave_seek /= n; //计算平均寻道长度

    printf("\nCSCAN寻道序列:\n");
    for(int i = 0; i < n; i++){
        printf("%d %d\n", cscan_seq[i][0], cscan_seq[i][1]);
    }
    printf("CSCAN平均寻道:%0.2lf\n", ave_seek);
}

//定义一个主函数,用于测试各种算法
int main(){
    int n; //磁道号序列的长度
    int cur; //磁头起始位置
    int dir; //初始移动方向,0表示向内(向小),1表示向外(向大)
    printf("请输入磁道号序列的长度:\n");
    scanf("%d", &n); //输入磁道号序列的长度
    disk list[n]; //定义一个结构体数组,用于存储磁道号和访问标志
    printf("请输入磁道号序列:\n");
    for(int i = 0; i < n; i++){
        scanf("%d", &list[i].track); //输入磁道号
        list[i].visited = 0; //初始化访问标志为0
    }
    printf("请输入磁头起始位置:\n");
    scanf("%d", &cur); //输入磁头起始位置
    printf("请输入初始移动方向(0表示向内,1表示向外):\n");
    scanf("%d", &dir); //输入初始移动方向

    FCFS(list, n, cur); //调用FCFS算法
    for(int i = 0; i < n; i++){
        list[i].visited = 0; //重置访问标志为0
    }
    SSTF(list, n, cur); //调用SSTF算法
    for(int i = 0; i < n; i++){
        list[i].visited = 0; //重置访问标志为0
    }
    SCAN(list, n, cur, dir); //调用SCAN算法
    for(int i = 0; i < n; i++){
        list[i].visited = 0; //重置访问标志为0
    }
    CSCAN(list, n, cur, dir); //调用CSCAN算法

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值