磁盘调度算法
磁盘调度主要应用于多道批处理系统中,以满足多个进程对磁盘读/写的请求。常用的磁盘调度算法有以下四种:
1. 先来先服务FCFS
此算法的优点是公平、简单,且每个进程 的请求都能依次得到处理,不会出现某进程的请求长期得不到 满足的情况。但此算法由于未对寻道进行优化,致使平均寻道 时间可能较长。 FCFS算法仅适用于请求磁盘I/O的进程数目较 少的场合。
代码写出来就是怎么输入就怎们输出。
2. 最短寻道时间优先SSTF
该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短。但这种调度算法不能保证平均寻道时间最短。
3. 扫描算法SCAN
扫描算法又叫做电梯算法。当有访问请求时,磁头按一个方向移动,判断该方向上是否还有访问请求,如果有则继续扫描;否则改变移动方向。相当于最短寻道再加上了一个方向。
4. 循环扫描算法CSCAN。
CSCAN算法规定磁头单向移动。例如,只自里向外移动,当磁头移到最外的被访问磁道时, 磁头立即返回到最里的欲访磁道,即将最小磁道号紧接着最大磁道号构成循环,进行扫描。
举个栗子吧
现有一个磁盘读写请求队列:55, 58,39,18,90,160,150,38,184,磁头当前位置为 100。
1.若采用 FCFS算法,序列就是:55、58、39、18、90、160、150、38、184,
移动距离依次为45、3、19、21、72、70、10、112、146 一共寻道9次,平均寻道时间是 55.3。
2.若采用 SSTF算法,序列就是:90、58、55、39、38、18、150、160、184
移动距离依次为10、32、3、16、1、20、132、10、24 一共寻道9次,平均寻道时间是 27.6。
3.若采用 SCAN算法,序列就是:150、160、184、90、58、55、39、38、18
移动距离依次为50、10、24、94、32、3、16、1、20 一共寻道9次,平均寻道时间是 27.8。
4.若采用 CSCAN算法,序列就是:150、160、184、18、38、39、55、58、90
移动距离依次为50、10、24、166、20、1、16、3、32 一共寻道9次,平均寻道时间是 35.8。
C语言代码如下 // 写了前三种算法
输入时,第一个数据应该输入磁头当前所在磁道
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define max 20
int CN;//柱面个数 Cylindrical Number
int CO[max];//柱面顺序 Cylindrical Order
void FCFS()
{
printf("\n---------------------FCFS-----------------------\n");
int sum = 0,i;
printf("柱面顺序: ");
for (i = 1; i < CN; i++)
printf("%-4d", CO[i]);
printf("\n移动距离: ");
for (i = 1; i < CN; i++)
{
int j = abs(CO[i] - CO[i - 1]);
printf("%-4d", j);
sum += j;
}
printf("\n一共移动了%d个柱面\n", sum);
}
void SSTF()
{
printf("\n---------------------SSTF-----------------------\n");
int i, j, copy[max];
int pos,min,temp;
int distance[max] = { 0 };
for (i = 0; i < CN; i++)
{
copy[i] = CO[i];
}
for (i = 1; i < CN; i++)
{
pos = i;
min = abs(copy[i] -copy[i - 1]);
for (j = i + 1; j < CN; j++)
{
if (abs(copy[j] - copy[i - 1]) < min)
{
min = abs(copy[j] - copy[i - 1]);
pos = j;
}
}
distance[i] = min;
if (pos != i)
{
temp = copy[pos];
copy[pos] = copy[i];
copy[i] = temp;
}
}
printf("柱面顺序: ");
for (i = 1; i < CN; i++)
printf("%-4d", copy[i]);
printf("\n移动距离: ");
for (i = 1; i < CN; i++)
{
j = distance[i];
printf("%-4d", j);
distance[0] += j;
}
printf("\n一共移动了%d个柱面\n",distance[0]);
}
void SCAN()
{
printf("\n---------------------SCAN-----------------------\n");
int choice,copy[max];
printf("请选择磁头移动方向 1.由外向里 2.由里向外 : ");
scanf("%d", &choice);
int i, j;
if (choice == 1)
{
j = 0;
for (i =0 ; i < CN;i++)
if (CO[i]>=CO[0])
copy[j++] = CO[i];
int n = j-1;
bool flag = true;
while (n > 1 && flag)
{
flag = false;
for (i = 0; i < n - 1;i++)
if (copy[i]>copy[i + 1])
{
int temp = copy[i];
copy[i] = copy[i + 1];
copy[i + 1] = temp;
flag = true;
}
n--;
}
int m = j;
for (i = 1; i < CN; i++)
if (CO[i] < CO[0])
copy[j++] = CO[i];
n = j;
flag = true;
while (n >= m&&flag)
{
flag = false;
for (i = m; i < n - 1;i++)
if (copy[i] < copy[i + 1])
{
int temp = copy[i];
copy[i] = copy[i + 1];
copy[i + 1] = temp;
flag = true;
}
n--;
}
}
else
{
j = 0;
for (i =0 ; i < CN;i++)
if (CO[i]<=CO[0])
copy[j++] = CO[i];
int n = j;
bool flag = true;
while (n > 1 && flag)
{
flag = false;
for (i = 0; i < n - 1;i++)
if (copy[i]<copy[i + 1])
{
int temp = copy[i];
copy[i] = copy[i + 1];
copy[i + 1] = temp;
flag = true;
}
n--;
}
int m = j;
for (i = 1; i < CN; i++)
if (CO[i] > CO[0])
copy[j++] = CO[i];
n = j;
flag = true;
while (n >= m&&flag)
{
flag = false;
for (i = m; i < n - 1;i++)
if (copy[i] > copy[i + 1])
{
int temp = copy[i];
copy[i] = copy[i + 1];
copy[i + 1] = temp;
flag = true;
}
n--;
}
}
printf("柱面顺序: ");
for (i = 1; i < CN; i++)
printf("%-4d", copy[i]);
int distance[max] = { 0 };
printf("\n移动距离: ");
for (i = 1; i < CN;i++ )
{
distance[i] = abs(copy[i] - copy[i - 1]);
printf("%-4d", distance[i]);
distance[0] += distance[i];
}
printf("\n一共移动了%d个柱面\n", distance[0]);
}
int main()
{
int i;
Test:printf("输入柱面个数: "); scanf("%d", &CN);
printf("输入柱面序列: ");
for (i = 0; i < CN; i++)
scanf("%d", &CO[i]);
FCFS();
SSTF();
SCAN();
int choice;
printf("是否继续测试? 是(1) 否(0) : "); scanf("%d", &choice);
if (choice == 1) goto Test;
else return 0;
}
测试数据:磁头最初位置为 125 ,输入数据
125、86、147、91、177、94、150、102、175、130