实验目的:
- 理解磁盘访问时间
- 掌握常用的磁盘调度算法
实验器材:
Vscode
实验内容:
对教材中所讲述的主要的磁盘调度算法进行深入分析,设计一个程序模拟实现一批作业的调度,并计算每种算法下的平均寻道时间。 编程实现三种磁盘调度算法:
- 先来先服务调度算法;
- 最短寻道优先调度算法:
- 扫描(电梯调度)算法;
- 循环扫描调度算法;
实验步骤:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define max 300
int num; //磁盘数
int request[100]; //请求磁盘序列
int begin; //开始磁盘位置
int sum; //横跨的总数
int k; //每次横跨的磁盘数
int re[100]; //复制初始序列
int r[100]; //记录每个算法执行后序列
int n, m;
void input();
void FIFO() { //先进先出
sum = abs(begin - request[0]);
printf("\n先进先出算法:\n FIFO调度: %3d", begin);
for (int i = 0; i < num; i++)
printf(" %3d", request[i]);
printf("\n 横跨磁道数为: %3d", abs(begin - request[0]));
for (int i = 1; i < num; i++) {
k = abs(request[i - 1] - request[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道长度: %.2f\n", 1.0 * sum / num);
}
int Smin(int b, int re[]) { //返回离开始磁盘b最近的磁盘下标
int min = abs(b - re[0]);//初始化横跨磁道数
int j = 0;
for (int i = 1; i < num; i++)
if (abs(b - re[i]) < min) {
min = abs(b - re[i]);
j = i;
}
return j;
}
void SSTF() { //最短寻道算法
int c = 0, b = begin;
printf("\n最短服务时间优先算法:\n SSTF调度: %3d", begin);
for (int i = 0; i < num; i++) {
c = Smin(b, re); //返回最近的磁道下标
b = re[c]; //将最近的磁盘作为开始
re[c] = 9999999; //将已经访问过的磁盘 设为很大值
printf(" %3d", b);
r[i] = b;
}
sum = abs(begin - r[0]);
printf("\n 横跨磁道数为: %3d", abs(begin - r[0]));//依次输出横跨的磁道数
for (int i = 1; i < num; i++) {
k = abs(r[i - 1] - r[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道时间: %.2f\n", 1.0 * sum / num);
}
void SCAN1() { //扫描算法
int c = 0, b = begin;
for (int i = 0; i < num; i++) //SSTF时re[]已改变
re[i] = request[i];
printf("\n扫描算法:\n SCAN调度: %3d", begin);
for (int i = 0; i < num - 1; i++) {
for (int j = 0; j < num - i - 1; j++) {
if (re[j] > re[j + 1]) {
re[j] = re[j] + re[j + 1];
re[j + 1] = re[j] - re[j + 1];
re[j] = re[j] - re[j + 1];
}
}
}
for (int i = 0; i < num; i++)
if (re[i] > b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
for (int i = num - 1; i >= 0; i--)
if (re[i] < b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
sum = abs(begin - r[0]);
printf("\n 横跨磁道数为: %3d", abs(begin - r[0]));
for (int i = 1; i < num; i++) {
k = abs(r[i - 1] - r[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道时间: %.2f\n", 1.0 * sum / num);
}
void SCAN2() { //扫描算法
int c = 0, b = begin;
for (int i = 0; i < num; i++) //SSTF时re[]已改变
re[i] = request[i];
printf("\n扫描算法:\n SCAN调度: %3d", begin);
for (int i = 0; i < num - 1; i++) {
for (int j = 0; j < num - i - 1; j++) {
if (re[j] < re[j + 1]) {
re[j] = re[j] + re[j + 1];
re[j + 1] = re[j] - re[j + 1];
re[j] = re[j] - re[j + 1];
}
}
}
for (int i = 0; i < num; i++)
if (re[i] < b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
for (int i = num - 1; i >= 0; i--)
if (re[i] > b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
sum = abs(begin - r[0]);
printf("\n 横跨磁道数为: %3d", abs(begin - r[0]));
for (int i = 1; i < num; i++) {
k = abs(r[i - 1] - r[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道时间: %.2f\n", 1.0 * sum / num);
}
void C_SCAN1() { //循环扫描
int c = 0, b = begin;
printf("\n循环扫描算法:\n CSCAN调度: %3d", begin);
for (int i = 0; i < num - 1; i++) {
for (int j = 0; j < num - i - 1; j++) {
if (re[j] > re[j + 1]) {
re[j] = re[j] + re[j + 1];
re[j + 1] = re[j] - re[j + 1];
re[j] = re[j] - re[j + 1];
}
}
}
for (int i = 0; i < num; i++)
if (re[i] > b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
for (int i = 0; i < num; i++)
if (re[i] < b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
sum = abs(begin - r[0]);
printf("\n 横跨磁道数为: %3d", abs(begin - r[0]));
for (int i = 1; i < num; i++) {
k = abs(r[i - 1] - r[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道时间: %.2f\n", 1.0 * sum / num);
}
void C_SCAN2() { //循环扫描
int c = 0, b = begin;
printf("\n循环扫描算法:\n CSCAN调度: %3d", begin);
for (int i = 0; i < num - 1; i++) {
for (int j = 0; j < num - i - 1; j++) {
if (re[j] < re[j + 1]) {
re[j] = re[j] + re[j + 1];
re[j + 1] = re[j] - re[j + 1];
re[j] = re[j] - re[j + 1];
}
}
}
for (int i = 0; i < num; i++)
if (re[i] < b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
for (int i = 0; i < num; i++)
if (re[i] > b) {
printf(" %3d", re[i]);
r[c++] = re[i];
}
sum = abs(begin - r[0]);
printf("\n 横跨磁道数为: %3d", abs(begin - r[0]));
for (int i = 1; i < num; i++) {
k = abs(r[i - 1] - r[i]);
printf(" %3d", k);
sum += k;
}
printf("\n 横跨的总磁道数: %3d", sum);
printf("\n 平均寻道时间: %.2f\n", 1.0 * sum / num);
}
void choose_algorithm() {
printf(" ******************\n *磁盘调度模拟实现*\n");
printf(" ******************\n\n\n");
printf(" *****************************************\n");
printf(" *****************************************\n");
printf(" ********1、先来先服务(FCFS)算法********\n");
printf(" ********2、最短寻道时间(SSTF)算法******\n");
printf(" ********3、扫描(SCAN)算法**************\n");
printf(" ********4、循环扫描(C_SCAN)算法********\n");
printf(" ********0、退出**************************\n");
printf(" *****************************************\n");
printf(" *****************************************\n\n\n");
printf("请选择磁盘调度算法: ");
scanf("%d", &n);
if (n == 1) {
input();
FIFO();
system("pause");
system("cls");
choose_algorithm();
} else if (n == 2) {
input();
SSTF();
system("pause");
system("cls");
choose_algorithm();
} else if (n == 3) {
input();
printf("1、由小到大 \n2、由大到小\n请选择磁头移动的方向:");
scanf("%d", &m);
if (m == 1) {
SCAN1();
system("pause");
system("cls");
choose_algorithm();
} else if (m == 2) {
SCAN2();
system("pause");
system("cls");
choose_algorithm();
} else {
printf("输入操作编号错误,请输入有效操作编号!");
system("pause");
system("cls");
choose_algorithm();
}
} else if (n == 4) {
input();
printf("1、由小到大 \n2、由大到小\n请选择磁头移动的方向:");
scanf("%d", &m);
if (m == 1) {
C_SCAN1();
system("pause");
system("cls");
choose_algorithm();
} else if (m == 2) {
C_SCAN2();
system("pause");
system("cls");
choose_algorithm();
} else {
printf("输入操作编号错误,请输入有效操作编号!");
system("pause");
system("cls");
choose_algorithm();
}
} else if (n == 0) {
exit(0);
} else {
printf("输入操作编号错误,请输入有效操作编号!");
system("pause");
system("cls");
choose_algorithm();
}
}
void input() {
printf("请输入调度磁道数量: ");
scanf("%d", &num);
printf("请输入磁道调度序列: ");
for (int i = 0; i < num; i++) {
scanf("%d", &request[i]);
re[i] = request[i];
}
printf("请输入当前磁道号: ");
scanf("%d", &begin);
return;
}
int main() {
choose_algorithm();
return 0;
}
实验结果(附数据和图表):
实验结果分析及结论:
完成了对先来先服务调度算法;最短寻道优先调度算法:扫描(电梯调度)算法的实现对于代码的逻辑以及几种算法的思想有了进一步的了解,对于一些细节方面的问题应该注意,fcfs在这三种算法中较为公平,但时间较长,其余几种可能会引起饥饿,但时间较短。
实验心得体会和建议:
对知识点有了更进一步的理解,同时对于一些算法的思想进一步认识,出现的一些问题也积极和别人商量,对不懂的问题与别人交流沟通,对整体的逻辑及核心思想有了深层次的体会,几种算法的优缺点及差异有较为明显的体现,对于三种算法的体会深刻,应继续学习对知识体系继续完善,补充不足之处。总之,这些磁盘调度算法各自有不同的特点和优缺点。在实际应用中,需要根据具体场景和需求选择合适的磁盘调度算法,以优化磁盘设备的使用效率和系统的整体性能。