操作系统的任务之一就是有效地使用硬件。
对磁盘驱动器,满足这一要求一位着要有较快的访问速度和较宽的磁盘宽带。
磁盘宽带是指所传递的总字节数除以从服务请求开始到最后传递结束时的总时间。
访问时间有寻道时间和旋转延迟两个主要部分。
寻道时间是磁臂将磁头移动到包含目标扇区的柱面的时间。
旋转延迟是磁盘需要将目标扇区转动到磁头下的时间。
通常,最小寻道时间可以用最少寻道距离来表示。
最常用的磁盘调度算法有以下几种:
1)先来先服务(FCFS)算法:根据进程请求访问磁盘的先后次序进行调度。算法的实现简单、公平;缺点:效率不高,相临两次请求可能会造成最内到最外的柱面寻道,使磁头反复移动,增加了服务时间,对机械也不利。
2)最短寻道时间优先(SSTF)算法:优先选择距当前磁头最近的访问请求进行服务,主要考虑寻道优先。优点:改善了磁盘平均服务时间;缺点:造成某些访问请求长期等待得不到服务。
3)扫描(SCAN)算法:当设备无访问请求时,磁头不动;当有访问请求时,磁头按一个方向移动,在移动过程中对遇到的访问请求进行服务,然后判断该方向上是否还有访问请求,如果有则继续扫描;否则改变移动方向,并为经过的访问请求服务,如此反复。克服了最短寻道优先的缺点,既考虑了距离,同时又考虑了方向。
4)循环扫描(C-SCAN)算法:总是从0号柱面开始向里扫描,按照各自所要访问的柱面位置的次序去选择访问者,移动臂到达最后一个柱面后,立即带动读写磁头快速返回到最小的需要方面的柱面,返回时不为任何的等待访问者服务,返回后可再次进行扫描。
调度算法的选择原则如下:
1)SSTF较为普遍且很有吸引力。
2)SCAN和C-SCAN对磁盘负荷较大的系统会执行得更好,这是因为它不可能产生饥饿问题。
3)对于任何调度算法,性能依赖于请求的类型和数量。
4)磁盘服务请求很大程度上收文件分配方法所影响。
5)磁盘调度算法应作为一个操作系统的独立模块。因为,如果有必要,可以方便替换成另外一种不同的算法。
6)SSTF或SCAN是比较合理地默认算法。
——————————————————————————————————————————————————————————————————————————————————————
以下是实验问题及过程:
1.现有8个进程先后提出的磁盘I/O请求 :98 138 37 122 14 124 65 67,当前磁头位置为53号磁道,磁头向内移动。分别采用FCFS算法、SSTF算法、SCAN算法以及C-SCAN算法,画出磁头移动的轨迹,计算平均寻道长度。
2.打开“Microsoft Visual C++ 6.0”,输入相关代码,对程序行进编译运行。在与源程序在同一目录下新建一个“cidao.txt”文件,内容为上述8个进程先后提出的磁盘I/O请求 :98 138 37 122 14 124 65 67。根据提示信息分别测试三种算法的最短寻道时间(假设当前磁头位置为53号磁道,磁头向内移动):
1)FCFS算法的测试结果是:
2)STF算法的测试结果是:
3)SCAN算法的测试结果是:
3.试模仿SCAN算法部分代码,在程序中再添加C-SCAN算法的实现,并对该算法进行测试。
(1)所添加的C-SCAN算法的代码:
#include<iostream>
using namespace std;
#define maxsize 100
void CElevator(int array[],int m){
int temp;
int k=1;
int now,l,r,d;
int i,j,sum=0;
for(i=0;i<m;i++)
for(j=i+1;j<m;j++){
if(array[i]>array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
for(i=0;i<m;i++){
cout<<array[i]<<" ";
}
cout<<"请输入当前的磁道号: ";
cin>>now;
if(array[m-1]<=now){
for(i=m-1;i>=0;i--)
cout<<array[i]<<" ";
sum=array[m-1]-now;
}
else{
while(array[k]<now){
k++;
}
l=k-1;
r=k;
cout<<"请输入当前移动臂的移动方向(1表示向内,0表示向外):";
cin>>d;
if(d==0){
for(j=l;j>=0;j--){
cout<<array[j]<<" ";
}
for(j=m-1;j>=k;j--){
cout<<array[j]<<" ";
}
sum=now-2*array[0]+array[m-1];
}
else{
for(j=r;j<m;j++){
cout<<array[j]<<" ";
}
for(j=0;j<k;j++){
cout<<array[j]<<" ";
}
sum=-now-array[0]+2*array[m-1];
}
}
cout<<"移动的总道数:"<<sum<<endl;
}
void main(){
FILE *fp;
int cidao[maxsize];
int i=0,count;
fp=fopen("cidao.txt","r+");
if(fp==NULL){
cout<<"文件打不开!"<<endl;
exit(0);
}
while(!feof(fp)){
fscanf(fp,"%d",&cidao[i]);
i++;
}
count=i;
for(i=0;i<count;i++){
printf("%5d",cidao[i]);
}
cout<<endl;
cout<<endl<<"系统的菜单如下:"<<endl;
printf("C-SCAN算法结果如下:");
cout<<endl;
CElevator(cidao,count);
}
(2)C-SCAN算法的测试结果是:
——————————————————————————————————————————————————————————————————————————————————————
附上源代码:
#include<iostream>
using namespace std;
#define maxsize 100
//先来先服务调度算法
void FCFS(int array[],int m){
int sum=0,j,i,now;
cout<<"请输入当前的的磁道号:";
cin>>now;
for(i=0;i<m;i++){
cout<<array[i]<<' ';
}
sum+=abs(now -array[0]);
for(i=0,j=1;j<m;i++,j++){
sum+=abs(array[j]-array[i]);
}
cout<<"移动的总道数: "<<sum<<endl;
}
//最短寻道时间优先调度算法
void ShortPath(int array[],int m){
int temp;
int k=1;
int now,l,r;
int i,j,sum=0;
for(i=0;i<m;i++){
for(j=i+1;j<m;j++){
if(array[i]>array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
for(i=0;i<m;i++){
cout<<array[i]<<endl;
}/*排序*/
cout<<"请输入当前磁道号:";
cin>>now;
if(array[m-1]<=now){
for(i=m-1;i>=0;i--)
cout<<array[i]<<" ";
sum=now-array[0];
}
else{
if(array[0]>=now){
for(i=0;i<m;i++)
cout<<array[i]<<" ";
sum=array[m-1]-now;
}
else{
while(array[k]<now){
k++;
}
l=k-1;
r=k;
}
/*确定当前磁道在已排的序列中的位置,后面的算法都用到了,可以直接复杂后少量修改,节约时间。*/
while((l>=0)&&(r<m)){
if((now-array[l])<=(array[r]-now)){
cout<<array[l]<<" ";
sum+=now-array[l];
now=array[l];
l=l-1;
}
}
if(l=-1){
for(j=r;j<m;j++){
cout<<array[j]<<" ";
}
sum+=array[m-1]-array[0];
}
else{
for(j=l;j>=0;j--){
cout<<array[j]<<" ";
}
sum+=array[m-1]-array[0];
}
}
cout<<"移动的总道数: "<<sum<<endl;
}
}
//电梯调度算法
void Elevator(int array[],int m){
int temp;
int k=1;
int now,l,r,d;
int i,j,sum=0;
for(i=0;i<m;i++)
for(j=i+1;j<m;j++){
if(array[i]>array[j]){
temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
for(i=0;i<m;i++){
cout<<array[i]<<" ";
}
cout<<"请输入当前的磁道号: ";
cin>>now;
if(array[m-1]<=now){
for(i=m-1;i>=0;i--)
cout<<array[i]<<" ";
sum=now-array[0];
}
else
if(array[0]>=now){
for(i=0;i<m;i++)
cout<<array[i]<<" ";
sum=array[m-1]-now;
}
else{
while(array[k]<now){
k++;
}
l=k+1;
r=k;
cout<<"请输入当前移动臂的移动方向(1表示向内,0表示向外):";
cin>>d;
if(d==0){
for(j=l;j>=0;j--){
cout<<array[j]<<" ";
}
for(j=r;j<m;j++){
cout<<array[j]<<" ";
}
sum=now-2*array[0]+array[m-1];
}
else{
for(j=r;j<m;j++){
cout<<array[j]<<" ";
}
for(j=i;j>=0;j--){
cout<<array[j]<<" ";
}
sum=-now-array[0]+2*array[m-1];
}
}
cout<<"移动的总道数:"<<sum<<endl;
}
void main(){
int c;
FILE *fp;
int cidao[maxsize];
int i=0,count;
fp=fopen("cidao.txt","r+");
if(fp==NULL){
cout<<"文件打不开!"<<endl;
exit(0);
}
while(!feof(fp)){
fscanf(fp,"%d",&cidao[i]);
i++;
}
count=i;
for(i=0;i<count;i++){
printf("%5d",cidao[i]);
}
cout<<endl;
while(1){
cout<<endl<<"系统的菜单如下:"<<endl;
printf("1.先来先服务 2.最短寻道时间优先 3.电梯调度");
cout<<endl;
printf("4.退出");
cout<<endl;
cout<<"请选择:";
cin>>c;
if(c>3)
break;
switch(c){
case 1:
FCFS(cidao,count);
break;
case 2:
ShortPath(cidao,count);
break;
case 3:
Elevator(cidao,count);
break;
}
}
}
我至今不知道那两个意大利娘儿们在唱什么,话说回来,我也不想知道,有些东西是无需言传的,我更相信那是因为它的美超出了语言所能形容的范畴。它美得让你为之心碎,我只能告诉你,那声音直入云霄,比这个灰暗角落里任何人所能梦想到的都更高更远,就像一只美丽的小鸟飞进我们乏味的牢笼,高墙因之消逝于无形之间,就是那一刻,每一个关在肖申克的失足者都触摸到了自由。