Ubuntu 20.04 LTS - x86_64
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)
我们将实验的完整代码放在了附录部分。
硬盘柱面访问调度算法的实现和CPU调度是相似的,我们将本实验中用到的几种调度策略列举如下:
标准用例均为:
initCylinder = 53
L = [98, 183, 37, 122, 14, 124, 65, 67]
顾名思义,FCFS调度根据请求发出的时间先后顺序决定硬盘柱面的访问顺序,并公平对待所有进程。
SSTF调度与SJF调度相似,CPU中的SJF调度策略选取当前队列中用时最少的进程优先执行,而SSTF策略则选取使得硬盘磁头的移动时间最小的请求。
SCAN调度是电梯算法的一种,很形象地,该算法就像电梯在楼宇中的运行一样,按照一个方向访问所有请求的楼层,再回头访问按反方向访问未满足的楼层。SCAN调度从初始柱面开始扫描,直到到达硬盘柱面最大(小)值,再反向开始扫描。
LOOK调度也是电梯算法的一种,它同SCAN调度的不同之处在于SCAN扫描到了硬盘柱面最大(小)值才反向扫描,而LOOK会事先检查最大(小)值,不需要扫描的硬盘边缘即可反向。
和SCAN调度相似,C-SCAN调度在到达硬盘边缘后不改变磁头扫描方向,而直接移动磁头到另一边缘继续访问。
和LOOK调度相似,C-LOOK调度在到达柱面请求的最大(小)值后不改变磁头扫描方向,而直接移动磁头到最小(大)值继续访问。
我们使用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]
initCylinder = 53
L1 = [189, 190, 12, 1, 0, 199]
结果如下所示:
经如上验证,本程序具备模拟硬盘访问六种调度策略的功能,实验结果是正确的。
硬盘访问调度算法的C语言实现同CPU调度算法的实现相比是容易的,在本次实验中我进一步加深了对于调度算法的理解,并且完成了简单的实现,对于操作系统的磁盘管理功能有了更深的理解。
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_ */
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 */
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 */