一、实验目的
要求模拟设计一个磁盘调度程序,观察调度程序的动态运行过程。通过实验让学生理解和掌握不同的磁盘调度算法的基本思想。
二、实验内容
对磁盘进行移臂操作,分别模拟FCFS、SSTF、SCAN、CSCAN四种磁盘调度算法计算移动的总磁道数和平均寻道长度。
三、实验准备
1.相关理论知识
(1)假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。
(2)磁盘是高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要求。系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。由于磁盘访问时间主要受寻道时间的影响,为此需要采用合适的寻道算法,以降低寻道时间。
(3)磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程提出输入输出请求而处于等待状态时,可用磁盘调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。
2.测试数据
磁盘读写请求队列对应的磁道号:20,44,40,4,80,12,76
当前磁头位置:50
试分别采用FCFS、SSTF、SCAN、CSCAN磁盘调度算法,输出每种调度算法下的寻道顺序,并计算出移动的总磁道数及平均寻道长度。
四、实验过程
流程图
源代码
#include <stdio.h>
#include <math.h>
#pragma warning(disable : 4996)
void FCFS(int a[], int n){
int sum = 0, j, i, now;
float ave;
printf(“请输入当前的磁道号:”);
scanf(“%d”,&now);
printf(“磁道调度顺序为:\n”);
for (i = 1; i < n; i++){
printf(" %d", a[i]);
}
for (i = 0, j = 1; j < n; i++, j++){
sum += abs(a[j] - a[i]);
ave = (float)(sum) / (n - 1);
}
printf(“\n”);
printf(“移动的总磁道数:%d\n”,sum);
printf(“平均寻道长度:%.2f\n”,ave);
}
void SSTF(int a[], int n){
int temp;
int k = 1;
int now, l, r;
int i, j, sum = 0;
float ave;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++){
if (a[i] > a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
printf(“按递增顺序排好的磁道号一次为:\n”);
for (i = 0; i < n; i++){
printf(" %d", a[i]);
}
printf(“\n”);
printf(“请输入当前的磁道号:”);
scanf(“%d”,&now);
printf(“磁盘扫描顺序为:\n”);
if (a[n - 1] == now){
for (i = n - 1; i >= 0; i–){
printf(" %d", a[i]);
}
sum = now - a[0];
}
if (a[0] == now){
for (i = 0; i < n; i++){
printf(" %d", a[i]);
}
sum = a[n - 1] - now;
}
if (now > a[0] && now < a[n - 1]){
while (a[k] < now){
k++;
}
l = k - 1;
r = k + 1;
while ((l >= 0) && (r < n)){
if ((now - a[l]) <= (a[r] - now)){
printf(" %d", a[l]);
sum += now - a[l];
now = a[l];
l = l - 1;
}
else{
printf(" %d", a[r]);
sum += a[r] - now;
now = a[r];
r = r + 1;
}
}
if (l == -1){
for (j = r; j < n; j++){
printf(" %d", a[j]);
}
sum += a[n - 1] - a[0];
}
else{
for (j = l; j >= 0; j–){
printf(" %d", a[j]);
}
sum += a[l] - a[0];
}
}
ave = (float)(sum) / (n - 1);
printf(“\n”);
printf(“移动的总磁道数:%d\n”,sum);
printf(“平均寻道长度:%.2f\n”,ave);
}
void SCAN(int a[], int n){
int temp;
int k = 1;
int now, l, r, f, t, w;
int i, j, sum = 0;
float ave;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++){
if (a[i] > a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
printf(“按递增顺序排好的磁道号依次为: \n”);
for (i = 0; i < n; i++){
printf(" %d", a[i]);
}
printf(“\n”);
printf(“请输入当前的磁道号:”);
scanf(“%d”,&now);
if (a[n - 1] == now){
printf(“磁盘扫描顺序为:\n”);
for (i = n - 2; i >= 0; i–)
printf(" %d", a[i]);
sum = now-a[0];
}
if (a[0] == now){
printf(“磁盘扫描顺序为:\n”);
for (i = 1; i<n; i++)
printf(" %d", a[i]);
sum = a[n - 1] - now;
}
if (now > a[0] && now < a[n - 1]){
while (a[k] < now){
k++;
}
l = k - 1;
r = k + 1;
printf(“请输入当前移动的方向(1 表示向外,0表示向内):”);
scanf(“%d”,&f);
printf(“磁盘扫描顺序为:\n”);
if (f == 0){
for (j = l; j >= 0; j–){
printf(" %d", a[j]);
t = now - a[j];
now = a[j];
sum += t;
}
for (j = r; j < n; j++){
printf(" %d", a[j]);
w = a[j] - now;
now = a[j];
sum = sum + w;
}
}
else{
for (j = r; j < n; j++){
printf(" %d", a[j]);
w = a[j] - now;
now = a[j];
sum = sum + w;
}
for (j = l; j >= 0; j–){
printf(" %d", a[j]);
t = now - a[j];
now = a[j];
sum += t;
}
}
}
ave = (float)(sum) / (n - 1);
printf(“\n”);
printf(“移动的总磁道数:%d\n”, sum);
printf(“平均寻道长度: %.2f\n”, ave);
}
void CSCAN(int a[], int n){
int temp;
int now, l, r, t, w;
int i, j, sum = 0;
int k = 1;
float ave;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++){
if (a[i] > a[j]){
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
printf(“按递增顺序排好的磁道号依次为: \n”);
for (i = 0; i < n; i++){
printf(" %d", a[i]);
}
printf(“\n”);
printf(“请输入当前的磁道号: “);
scanf(”%d”,&now);
if (a[n - 1] == now){
for (i = n - 2; i >= 0; i–)
printf(" %d “, a[i]);
sum = now - a[0];
}
if (a[0] == now){
for (i = 1; i < n; i++)
printf(” %d “, a[i]);
sum = a[n - 1] - now;
}
if (now > a[0] && now < a[n - 1]){
while (a[k] < now){
k++;
}
l = k - 1;
r = k + 1;
for (j = r; j < n; j++){
printf(” %d “, a[j]);
w = a[j] - now;
now = a[j];
sum += w;
}
for (j = 0; j <= l; j++){
printf(” %d “, a[j]);
t = abs(now - a[j]);
now = a[j];
sum += t;
}
}
ave = (float)(sum) / (n - 1);
printf(”\n");
printf(“移动的总磁道数: %d\n”, sum);
printf(“平均寻道长度: %.2f\n”,ave);
}
int main(){
int n;
int s;
printf(“请输入磁道的个数: “);
scanf(”%d”, &n);
int* a = new int[n];
printf(“请依次输入要访问的磁道号(包含当前磁头所在的磁道): “);
for (int i = 0; i < n; i++)
scanf(”%d”, &a[i]);
while (1){
printf(“\n”);
printf(“-------磁盘调度算法-------\n”);
printf(“–1、先来先服务算法(FCFS) \n”);
printf(“–2、最短寻道时间优先算法(SSTF) \n”);
printf(“–3、扫描算法(SCAN) \n”);
printf(“–4、循环扫描算法(CSCAN) \n”);
printf(“–5、退出\n”);
printf(“\n”);
printf(“请选择1-5中任意一个数字:”);
scanf(“%d”, &s);
switch (s){
case 1:
FCFS(a, n);
break;
case 2:
SSTF(a, n);
break;
case 3:
SCAN(a, n);
break;
case 4:
CSCAN(a, n);
break;
case 5:
return 0;
default:printf(“输入错误,请重新输入!\n”);
}
}
return 0;
}
运行界面
五、实验心得
本次实验通过模拟磁盘调度及进程排队算法来加深对操作系统中各个磁臂调度算法概念的理解。模拟磁盘调度算法(FCFS,SSTF,SCAN,CSCAN),实现各种不同调度算法的过程,并计算各算法的平均寻道长度,以便于我们判断各种算法的优劣以及各种算法使用的场合。
通过本次实验,学习了解磁盘调度的工作原理及四种调度方法的工作原理,并且在当中发现了自己的不足,对以前所学过的知识理解得不够深刻,掌握得不够牢固,看到了自己的实践经验还是比较缺乏,理论联系实际的能力还急需提高。