一、实验目的
1、了解磁盘调度的策略和原理;
2、理解和掌握磁盘调度算法——先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、电梯扫描算法(SCAN)。
二、实验内容
1、模拟先来先服务法(First-Come, First-Served,FCFS),最短寻道时间优先法(Shortest Seek Time First, SSTF),电梯扫描算法(SCAN)三种磁盘调度算法;
2、对三种算法进行对比分析。
3、输入为一组请求访问磁道序列,输出为每种调度算法的磁头移动轨迹和移动的总磁道数。
三、实验原理
1、先来先服务算法(FCFS)
按先来后到次序服务,未作优化。最简单的移臂调度算法是“先来先服务”调度算法,这个算法实际上不考虑访问者要求访问的物理位置,而只是考虑访问者提出访问请求的先后次序。 采用先来先服务算法决定等待访问者执行输入输出操作的次序时,移动臂来回地移动。先来先服务算法花费的寻找时间较长,所以执行输入输出操作的总时间也很长。
2、最短寻道时间优先算法(SSTF)
最短寻找时间优先调度算法总是从等待访问者中挑选寻找时间最短的那个请求先执行的,而不管访问者到来的先后次序。与先来先服务、算法比较,大幅度地减少了寻找时间,因而缩短了为各访问者请求服务的平均时间,也就提高了系统效率。但最短查找时间优先(SSTF)调度,FCFS会引起读写头在盘面上的大范围移动,SSTF查找距离磁头最短(也就是查找时间最短)的请求作为下一次服务的对象。SSTF查找模式有高度局部化的倾向,会推迟一些请求的服务,甚至引起无限拖延(又称饥饿)。
3、扫描算法(SCAN)
SCAN 算法又称电梯调度算法。SCAN算法是磁头前进方向上的最短查找时间优先算法,它排除了磁头在盘面局部位置上的往复移动,SCAN算法在很大程度上消除了SSTF算法的不公平性,但仍有利于对中间磁道的请求。“电梯调度”算法是从移动臂当前位置开始沿着臂的移动方向去选择离当前移动臂最近的那个柱访问者,如果沿臂的移动方向无请求访问时,就改变臂的移动方向再选择。但是,“电梯调度”算法在实现时,不仅要记住读写磁头的当前位置,还必须记住移动臂的当前前进方向。
四、实验中用到的系统调用函数(包括实验原理中介绍的和自己采用的),自己采用的系统调用函数要按照指导书中的格式说明进行介绍。
因为是模拟程序,可以不使用系统调用函数。
五、实验步骤
1、 输入为一组请求访问磁道序列,该序列和所选磁道个数要求随机生成,输出为每种调度算法的磁头移动轨迹和移动的总磁道数;
2、输入磁道范围01000,输入所选磁道个数01000
3、画出实验主程序流程图
4、编写程序并调试
5、截屏输出实验结果
6、根据结果进行分析
实验流程图
先来先服务算法(FCFS)
最短寻道时间优先算法(SSTF)
电梯扫描算法(SCAN)
六、实验数据及源代码(学生必须提交自己设计的程序源代码,并有注释,源代码电子版也一并提交),包括思考题的程序。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<time.h>
int N;//磁道总数
int start;//磁头位置
int* seq;//请求访问磁道序列
void init() {
N = rand() % 1001;//随机生成磁道总数
start = rand() & 1001;//随机生成初始磁头位置
seq = new int [N];//请求访问磁道序列
for (int i = 0; i < N; i++) {
seq[i] = rand() % 1001;
}
printf("初始化随机生成磁道总数为:%d\n", N);
printf("随机生成的请求访问磁道序列为:");
for (int i = 0; i < N; i++)
printf("%d ", seq[i]);
printf("\n随机生成的初始磁头位置为:%d\n\n", start);
}
void release() {//进程完成,释放资源
free(seq);
}
void FCFS() {//先来先服务算法
int steps = 0,move=start;
printf("磁头移动轨迹为:%d", start);
for (int i = 0; i < N; i++) {
printf("->%d", seq[i]);
steps += abs(seq[i] - move);
move = seq[i];
}
printf("\n移动磁道数为:%d\n\n", steps);
}
void SSTF() {//最短寻道时间优先算法
int steps = 0, move = start, flag, step = 100000;
int* record = new int[N];//记录磁道是否已经访问过
for (int i = 0; i < N; i++)
record[i] = 0;
printf("磁头移动轨迹为:%d", start);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {//找出寻道时间最短的那个磁道
if (record[j] == 0) {
if (step > abs(seq[j] - move)) {
step=abs(seq[j]-move);
flag=j;
}
}
}
steps += step;
record[flag] = 1;
move = seq[flag];
step = 100000;
printf("->%d", move);
}
printf("\n移动磁道数为:%d\n\n", steps);
}
void quickSort(int* seq, int low, int high) {//快速排序算法,用于电梯扫描算法中
if (low < high) {
int i = low, j = high;
int temp = seq[i];
while (i < j) {
while (i < j && seq[j] >= temp) {
j--;
}
if (i < j) {
seq[i++] = seq[j];
}
while (i < j && seq[i] <= temp) {
i++;
}
if (i < j) {
seq[j--] = seq[i];
}
}
seq[i] = temp;
quickSort(seq, low, i - 1);
quickSort(seq, i + 1, high);
}
}
void SCAN() {//电梯扫描算法
int flag=N, steps=0, move = start;
quickSort(seq, 0, N - 1);//快速排序(升序)
for (int i = 0; i < N; i++) {
if (seq[i] > start) {
flag = i;
break;
}
}
int direction = rand() % 2;//随机初始磁头访问方向,0表示先向左访问,1表示先向右访问
printf("磁头移动轨迹为:%d", start);
if (direction == 0) {//先向左访问
for (int i = flag - 1; i >= 0; i--) {
steps += abs(seq[i] - move);
move = seq[i];
printf("->%d", move);
}
for (int i = flag; i < N; i++) {
steps += abs(seq[i] - move);
move = seq[i];
printf("->%d", move);
}
printf("\n移动磁道数为:%d\n\n", steps);
}
else {//先向右访问
for (int i = flag; i < N; i++) {
steps += abs(seq[i] - move);
move = seq[i];
printf("->%d", move);
}
for (int i = flag - 1; i >= 0; i--) {
steps += abs(seq[i] - move);
move = seq[i];
printf("->%d", move);
}
printf("\n移动磁道数为:%d\n", steps);
}
}
int main() {
srand((unsigned)time(NULL));
init();
printf("*****************先来先服务算法(FCFS)*****************\n");
FCFS();
printf("*****************最短寻道时间优先算法(SSTF)*****************\n");
SSTF();
printf("*****************电梯扫描算法算法(SCAN)*****************\n");
SCAN();
release();
}
七、实验结果分析(截屏的实验结果,与实验结果对应的实验分析)