中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18

Labwork18 - HardDisk Schedule

编译环境

Ubuntu 20.04 LTS - x86_64
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

实验内容:硬盘调度

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

实验过程

一、实验准备

我们将实验的完整代码放在了附录部分。

原理理论

硬盘柱面访问调度算法的实现和CPU调度是相似的,我们将本实验中用到的几种调度策略列举如下:

标准用例均为:

initCylinder = 53
L = [98, 183, 37, 122, 14, 124, 65, 67]
  1. FCFS调度

顾名思义,FCFS调度根据请求发出的时间先后顺序决定硬盘柱面的访问顺序,并公平对待所有进程。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第1张图片
2. SSTF调度

SSTF调度与SJF调度相似,CPU中的SJF调度策略选取当前队列中用时最少的进程优先执行,而SSTF策略则选取使得硬盘磁头的移动时间最小的请求。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第2张图片
3. SCAN调度(电梯算法)

SCAN调度是电梯算法的一种,很形象地,该算法就像电梯在楼宇中的运行一样,按照一个方向访问所有请求的楼层,再回头访问按反方向访问未满足的楼层。SCAN调度从初始柱面开始扫描,直到到达硬盘柱面最大(小)值,再反向开始扫描。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第3张图片

  1. LOOK调度(电梯算法)

LOOK调度也是电梯算法的一种,它同SCAN调度的不同之处在于SCAN扫描到了硬盘柱面最大(小)值才反向扫描,而LOOK会事先检查最大(小)值,不需要扫描的硬盘边缘即可反向。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第4张图片

  1. C-SCAN调度(电梯算法)

和SCAN调度相似,C-SCAN调度在到达硬盘边缘后不改变磁头扫描方向,而直接移动磁头到另一边缘继续访问。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第5张图片

  1. C-LOOK调度(电梯算法)

和LOOK调度相似,C-LOOK调度在到达柱面请求的最大(小)值后不改变磁头扫描方向,而直接移动磁头到最小(大)值继续访问。

调度示意图如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第6张图片

二、实验实现

我们使用C程序模拟了硬盘访问调度算法。

硬盘的数据结构如下所示:

typedef struct disk {
    int size;
    int initCylinders;
    int* queue;
    int queueLen;
} Disk;

三、实验结果

我们分别实现了所要求的 FCFS、SSTF、SCAN、C-SCAN、LOOK、C-LOOK 六种硬盘访问调度算法,首先使用第一部分中给出的标准用例进行测试:

initCylinder = 53
L = [98, 183, 37, 122, 14, 124, 65, 67]

结果如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第7张图片
设计包括了硬盘边缘的测试用例进行测试:

initCylinder = 53
L1 = [189, 190, 12, 1, 0, 199]

结果如下所示:
中山大学软件工程 操作系统原理 蔡国扬 硬盘调度 - Labweek_18_第8张图片
经如上验证,本程序具备模拟硬盘访问六种调度策略的功能,实验结果是正确的。

四、实验心得

硬盘访问调度算法的C语言实现同CPU调度算法的实现相比是容易的,在本次实验中我进一步加深了对于调度算法的理解,并且完成了简单的实现,对于操作系统的磁盘管理功能有了更深的理解。

附录、实验代码

  1. source.h
#ifndef _SOURCE_H_
#define _SOURCE_H_

#include 
#include 

#define boolean int
#define true 1
#define false 0
#define nullptr NULL

typedef struct disk {
    int size;
    int initCylinders;
    int* queue;
    int queueLen;
} Disk;

Disk* initDisk(int*, int, int, int);
void destoryDisk(Disk*);
void FCFS(Disk*);
void SSTF(Disk*);
void SCAN(Disk*);
void CSCAN(Disk*);
void LOOK(Disk*);
void CLOOK(Disk*);

#endif /* _SOURCE_H_ */
  1. source.c
#include "source.h"


Disk* initDisk(int* L, int init, int size, int len)
{
    Disk* d;
    d = (Disk*)malloc(sizeof(Disk));
    d->initCylinders = init;
    d->queue = (int*)malloc(sizeof(int) * len);
    for ( int i = 0; i < len; ++i ) {
        d->queue[i] = L[i];
    }
    d->queueLen = len;
    d->size = size;
    return d;
}

void destoryDisk(Disk* d)
{
    free(d->queue);
    free(d);
}

void FCFS(Disk* d)
{
    printf("---------------- FCFS -------------------\n");
    printf("InitCylinder is %d. The size disk is %d. \nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = 0; i < d->queueLen; ++i ) {
        printf("%d ", d->queue[i]);
    }
    printf("\nFCFS Scheduling ends.\n\n");
}

void SSTF(Disk* d)
{
    int* flags = (int*)malloc(sizeof(int) * d->queueLen);
    int ptr = 0;
    int value = d->initCylinders;

    for ( int i = 0; i < d->queueLen; ++i ) {
        flags[i] = 0;
    }

    printf("---------------- SSTF -------------------\n");
    printf("InitCylinder is %d. The size disk is %d.\nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = 0; i < d->queueLen; ++i ) {
        int j;
        int min = d->size;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && abs(value - d->queue[j]) < min ) {
                min = abs(value - d->queue[j]);
                ptr = j;
            }
        }
        flags[ptr] = 1;
        value = d->queue[ptr];
        printf("%d ", d->queue[ptr]);
    }
    printf("\nSSTF Scheduling ends.\n\n");
    free(flags);
}

void SCAN(Disk* d)
{
    int times = 0;
    int* flags = (int*)malloc(sizeof(int) * d->queueLen);
    int value = d->initCylinders;

    for ( int i = 0; i < d->queueLen; ++i ) {
        flags[i] = 0;
    }

    printf("---------------- SCAN -------------------\n");
    printf("InitCylinder is %d. The size disk is %d.\nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = value; i >= 0; --i ) {
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( i == 0 && !truth ) {
            printf("(0) ");
        }
    }
    for ( int i = 0; i < d->size; ++i ) {
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( times == d->queueLen) {
            break;
        }
    }
    printf("\nSCAN Scheduling ends.\n\n");
    free(flags);
}

void LOOK(Disk* d)
{
    int min = d->size;
    for ( int i = 0; i < d->queueLen; ++i ) {
        if ( min > d->queue[i] ) {
            min = d->queue[i];
        }
    }
    int times = 0;
    int* flags = (int*)malloc(sizeof(int) * d->queueLen);
    int value = d->initCylinders;

    for ( int i = 0; i < d->queueLen; ++i ) {
        flags[i] = 0;
    }

    printf("---------------- LOOK -------------------\n");
    printf("InitCylinder is %d. The size disk is %d.\nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = d->initCylinders; i >= min; --i ) {
        // printf("CHECKPOINT1 %d %d\n", i, min);
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( i == min ) {
            // printf("CHECKPOINT2\n");
            break;
        }
    }
    for ( int i = 0; i < d->size; ++i ) {
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( times == d->queueLen ) {
            break;
        }
    }
    printf("\nLOOK Scheduling ends.\n\n");
    free(flags);
}

void CSCAN(Disk* d)
{
    int times = 0;
    int* flags = (int*)malloc(sizeof(int) * d->queueLen);
    int value = d->initCylinders;
    boolean reverse = true;

    for ( int i = 0; i < d->queueLen; ++i ) {
        flags[i] = 0;
    }

    printf("---------------- C-SCAN -------------------\n");
    printf("InitCylinder is %d. The size disk is %d.\nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = d->initCylinders; i != d->initCylinders - 1; ++i ) {
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( i == d->size - 1 && !truth ) {
            printf("(%d) (%d) ", d->size - 1, 0);
        }
        if ( i == d->size - 1 ) {
            i = -1;
        }
        if ( times == d->queueLen ) {
            break;
        }
    }
    printf("\nC-SCAN Scheduling ends.\n\n");
    free(flags);
}

void CLOOK(Disk* d)
{
    int min = d->size;
    int max = 0;
    for ( int i = 0; i < d->queueLen; ++i ) {
        if ( min > d->queue[i] ) {
            min = d->queue[i];
        }
        if ( max < d->queue[i] ) {
            max = d->queue[i];
        }
    }
    int times = 0;
    int* flags = (int*)malloc(sizeof(int) * d->queueLen);
    int value = d->initCylinders;

    for ( int i = 0; i < d->queueLen; ++i ) {
        flags[i] = 0;
    }

    printf("---------------- C-LOOK -------------------\n");
    printf("InitCylinder is %d. The size disk is %d.\nThe schedule is:\n", d->initCylinders, d->queueLen);
    for ( int i = d->initCylinders; i != d->initCylinders - 1; ++i ) {
        boolean truth = false;
        int j;
        for ( j = 0; j < d->queueLen; ++j ) {
            if ( flags[j] == 0 && i == d->queue[j] ) {
                truth = true;
                break;
            }
        }
        if ( truth ) {
            printf("%d ", d->queue[j]);
            flags[j] = 1;
            ++times;
        }
        if ( i == max ) {
            i = min - 1;
        }
        if ( times == d->queueLen ) {
            break;
        }
    }
    printf("\nC-LOOK Scheduling ends.\n\n");
    free(flags);
}
/* end */
  1. main.c
#include "source.h"

int main (void)
{
    Disk* disk;
    int init = 53;
    int L[] = { 98, 183, 37, 122, 14, 124, 65, 67, };
    int L1[] = { 189, 190, 12, 1, 0, 199, };
    disk = initDisk(L, init, 200, sizeof(L) / sizeof(int));

    printf("The access queue is: \n");
    for ( int i = 0; i < disk->queueLen; ++i ) {
        printf("%d ", disk->queue[i]);
    }
    putchar('\n');

    FCFS(disk);
    SSTF(disk);
    SCAN(disk);
    LOOK(disk);
    CSCAN(disk);
    CLOOK(disk);

    destoryDisk(disk);

    return 0;
}

/* end */

你可能感兴趣的:(操作系统,操作系统,c++)