labweek18

实验报告

实验内容

硬盘调度: 编写 C 程序模拟实现课件 Lecture25 中的硬盘柱面访问调度算法包括 FCFS、SSTF、SCAN、C-SCAN、LOOK、C-LOOK,并设计输入用例验证结果。

实验环境

 Ubuntu 20.04.2.0(64位)

基础知识

  1. FCFS(先来先服务): 根据进程请求访问磁盘的先后顺序进行调度。

例1:
在这里插入图片描述

例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。
在这里插入图片描述

  1. SSTF(最短寻道时间优先):其要求访问的磁道与当前磁头所在的磁道距离最近。

例1:
在这里插入图片描述

例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。
在这里插入图片描述

  1. SCAN(扫描算法): 磁臂从磁盘的一端开始向另一端移动,在到达每个柱面时为请求提供服务,直到到达磁盘的另一端,磁头的移动方向相反,服务继续进行。

例1:
在这里插入图片描述

例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。向磁道号增加方向访问。
在这里插入图片描述

  1. LOOK: LOOK就是对应SCAN的改进算法。因为SCAN中每次磁头都要走到磁道尽头,而实际过程中并不需要要求磁头走到尽头,而是到达该方向的最后一个请求后即可返回,这样可以避免一些不必要的磁头移动。

例1:
在这里插入图片描述

例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。向磁道号增加方向访问。
在这里插入图片描述

  1. CSCAN(循环扫描算法): 首先自里向外访问,当磁头移到最外的磁道后,磁头返回到最里的磁道,即将最小磁道号紧接着最大磁道号构成循环,继续循环扫描。

例1:
在这里插入图片描述

例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。
在这里插入图片描述

  1. CLOOK: CLOOK就是对应CSCAN的改进算法。因为CSCAN中每次磁头都要走到磁道尽头,而实际过程中并不需要要求磁头走到尽头,而是到达该方向的最后一个请求后即可返回,这样可以避免一些不必要的磁头移动。

例1:
在这里插入图片描述
例2:

如磁道请求队列为55、58、39、18、90、160、150、38、184,从100号开始。
在这里插入图片描述

参考资料1:课件

参考资料2

实验过程

规定硬盘只有200个磁道,从0~199:
在这里插入图片描述

一. 用以上例2作为输入样例:
在这里插入图片描述

  1. FCFS结果:
    在这里插入图片描述
    与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

  2. SSTF结果:
    在这里插入图片描述
    与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

  3. SCAN结果:
    在这里插入图片描述
    可以看到,磁头需要走到磁盘一端的最后一个磁道才会往回移动,其他与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

  4. CSCAN结果:
    在这里插入图片描述
    可以看到,磁头需要走到磁盘一端的最后一个磁道才会往回移动,其他与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

  5. LOOK结果:
    在这里插入图片描述
    可以看到,磁头只需要走到其方向上的最后一个请求即可往回移动,与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

  6. CLOOK结果:
    在这里插入图片描述
    可以看到,磁头只需要走到其方向上的最后一个请求即可往回移动,与例2中的结果一致,计算所得的总寻道长度和平均寻道长度也正确。

一. 用以上例1作为另一输入样例:
在这里插入图片描述

  1. FCFS结果:
    在这里插入图片描述

  2. SSTF结果:
    在这里插入图片描述

  3. SCAN结果:
    在这里插入图片描述

  4. CSCAN结果:
    在这里插入图片描述

  5. LOOK结果:
    在这里插入图片描述

  6. CLOOK结果:
    在这里插入图片描述

代码

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

#define MAX_TASK 100
#define MAX_track 199

#define waiting 0
#define complete 1

// structure of task
typedef struct task
{
    int track;      // task's track
    int stat;       // task's state: wait or complete
} Task;  

// structure of read-write head
typedef struct head
{
    int track;      // head's track
    int seek_length;  // total seek length
} Head; 

void FCFS(Task task[], Head head, int task_n);
void SSTF(Task task[], Head head, int task_n);
void SCAN(Task task[], Head head, int task_n);
void CSCAN(Task task[], Head head, int task_n);
void LOOK(Task task[], Head head, int task_n);
void CLOOK(Task task[], Head head, int task_n);

int main()
{
    printf("In this hard disk, the tracks is from 0 to %d.\n", MAX_track);

    printf("\n");
    int task_n = 9; // the number of tasks
    printf("Please enter the number of task(<=100): ");
    scanf("%d", &task_n);
    if(task_n > 100){
        printf("Error: value out of range!\n");
        return -1;
    }

    printf("\n");
    printf("Please enter the track in each task:\n");
    Task task[task_n];      // array of task
    for(int i = 0; i < task_n; i++){
        printf("task %d(0 ~ %d): ", i, MAX_track);
        scanf("%d", &task[i].track);
        if(task[i].track > MAX_track || task[i].track < 0){
            printf("Error: value out of range!\n");
            return -1;
        }

        task[i].stat = waiting;     // initialize task's state
    }
    // task[0].track = 55;
    // task[1].track = 58;
    // task[2].track = 39;
    // task[3].track = 18;
    // task[4].track = 90;
    // task[5].track = 160;
    // task[6].track = 150;
    // task[7].track = 38;
    // task[8].track = 184;

    printf("\n");
    Head head;
    int head_track;
    printf("Please enter initial track of read-write head(0 ~ %d): ", MAX_track);
    scanf("%d", &head_track);
    if(head_track > MAX_track || head_track < 0){
        printf("Error: value out of range!\n");
        return -1;
    }

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_FCFS[task_n];
    for(int i = 0; i < task_n; i++){
        task_FCFS[i].track = task[i].track;
        task_FCFS[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: FCFS.\n");
    FCFS(task_FCFS, head, task_n);

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_SSTF[task_n];
    for(int i = 0; i < task_n; i++){
        task_SSTF[i].track = task[i].track;
        task_SSTF[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: SSTF.\n");
    SSTF(task_SSTF, head, task_n);

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_SCAN[task_n];
    for(int i = 0; i < task_n; i++){
        task_SCAN[i].track = task[i].track;
        task_SCAN[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: SCAN.\n");
    printf("Assume that the disk arm is moving toward 199.\n");
    SCAN(task_SCAN, head, task_n);

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_CSCAN[task_n];
    for(int i = 0; i < task_n; i++){
        task_CSCAN[i].track = task[i].track;
        task_CSCAN[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: CSCAN.\n");
    CSCAN(task_CSCAN, head, task_n);

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_LOOK[task_n];
    for(int i = 0; i < task_n; i++){
        task_LOOK[i].track = task[i].track;
        task_LOOK[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: LOOK.\n");
    printf("Assume that the disk arm is moving toward 199.\n");
    LOOK(task_LOOK, head, task_n);

    printf("\n");
    // creat copy
    head.track = head_track;
    head.seek_length = 0;
    Task task_CLOOK[task_n];
    for(int i = 0; i < task_n; i++){
        task_CLOOK[i].track = task[i].track;
        task_CLOOK[i].stat = task[i].stat;
    }
    printf("Scheduling Mode: CLOOK.\n");
    CLOOK(task_CLOOK, head, task_n);

    return 0;
}

void FCFS(Task task[], Head head, int task_n)
{
    printf("track visited\tseek length\n");

    for(int i = 0; i < task_n; i++){
        task[i].stat = complete;

        int temp = abs(task[i].track - head.track);     // absolute value: distance between track and head
        printf("%13d\t%11d\n", task[i].track, temp);

        head.track = task[i].track;
        head.seek_length += temp;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.1f.\n", 1.0 * head.seek_length/task_n);
}

void SSTF(Task task[], Head head, int task_n)
{
    printf("track visited\tseek length\n");
    
    for(int i = 0; i < task_n; i++){
        int min_dis = 200;  // the least distance from the head
        int min_task = 0;      // the track with the least distance from the head
        int temp = 0;       // absolute value: distance between track and head
        
        for(int j = 0; j < task_n; j++){    // find the task with the least distance from the head
            if(task[j].stat == waiting){
                temp = abs(task[j].track - head.track);
                if(temp < min_dis){
                    min_dis = temp;
                    min_task = j;
                }
            }            
        }

        printf("%13d\t%11d\n", task[min_task].track, min_dis);

        head.track = task[min_task].track;
        head.seek_length += min_dis;
        task[min_task].stat = complete;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.2f.\n", 1.0 * head.seek_length/task_n);
}

void SCAN(Task task[], Head head, int task_n)
{
    printf("track visited\tseek length\n");

    int temp_head = head.track;

    while(temp_head <= MAX_track){      // head: from head track to max track 
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    while(temp_head >= 0){      // head: from max track to 0
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head--;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.1f.\n", 1.0 * head.seek_length/task_n);
}

void CSCAN(Task task[], Head head, int task_n)
{
    printf("track visited\tseek length\n");

    int temp_head = head.track;

    while(temp_head <= MAX_track){      // head: from head track to max track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    temp_head = 0;      // head: back to the beginning

    while(temp_head <= MAX_track){      // head: from beginning to max track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.1f.\n", 1.0 * head.seek_length/task_n);
}

void LOOK(Task task[], Head head, int task_n)
{
    int min_track = 200;
    int max_track = -1;
    for(int i = 0; i < task_n; i++){        // find min task's track and max task's track
        if(task[i].track < min_track){
            min_track = task[i].track;
        }
        
        if(task[i].track > max_track){
            max_track = task[i].track;
        }
    }

    printf("track visited\tseek length\n");

    int temp_head = head.track;
    
    while(temp_head <= max_track){      // head: from head track to max task's track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    while(temp_head >= min_track){      // head: from max task's track to min task's track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head--;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.1f.\n", 1.0 * head.seek_length/task_n);
}

void CLOOK(Task task[], Head head, int task_n)
{
    int min_track = 200;
    int max_track = -1;
    for(int i = 0; i < task_n; i++){        // find min task's track and max task's track
        if(task[i].track < min_track){
            min_track = task[i].track;
        }
        
        if(task[i].track > max_track){
            max_track = task[i].track;
        }
    }

    printf("track visited\tseek length\n");

    int temp_head = head.track;
    
    while(temp_head <= max_track){      // head: from head track to max task's track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    temp_head = min_track;      // head: back to min task's track

    while(temp_head <= max_track){      // head: from min task's track to max task's track
        for(int i = 0; i < task_n; i++){
            if(task[i].stat == waiting){
                if(task[i].track == temp_head){
                    task[i].stat = complete;

                    int temp = abs(task[i].track - head.track);
                    printf("%13d\t%11d\n", task[i].track, temp);

                    head.track = task[i].track;
                    head.seek_length += temp;
                    break;
                }
            }
        }

        temp_head++;
    }

    printf("Total seek length: %d.\n", head.seek_length);
    printf("Average seek length: %.1f.\n", 1.0 * head.seek_length/task_n);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值